SQL 迭代
在处理关系数据库表时,经常会说 “我需要针对表中的每一行执行操作”。比较一下前面的例子。您很可能会说 “我需要对列表中的每一种语言执行一些操作”。根据这个道理,groovy.sql.Sql 对象提供了一个 eachRow() 方法,如清单 17 所示:
清单 17. ResultSet 迭代
import groovy.sql.*
def sql = Sql.newInstance(
"jdbc:derby://localhost:1527/MyDbTest;create=true",
"username",
"password",
"org.apache.derby.jdbc.ClientDriver")
println("grab a specific field")
sql.eachRow("select name from languages"){ row ->
println row.name
}
println("grab all fields")
sql.eachRow("select * from languages"){ row ->
println("Name: ${row.name}")
println("Version: ${row.version}")
println("URL: ${row.url}\n")
}
def sql = Sql.newInstance(
"jdbc:derby://localhost:1527/MyDbTest;create=true",
"username",
"password",
"org.apache.derby.jdbc.ClientDriver")
println("grab a specific field")
sql.eachRow("select name from languages"){ row ->
println row.name
}
println("grab all fields")
sql.eachRow("select * from languages"){ row ->
println("Name: ${row.name}")
println("Version: ${row.version}")
println("URL: ${row.url}\n")
}
该脚本的第一行代码实例化了一个新的 Sql 对象:设置 JDBC 连接字符串、用户名、密码和 JDBC 驱动器类。这时,可以调用 eachRow() 方法,传递 SQL select 语句作为一个方法参数。在闭包内部,可以引用列名(name、version、url),就好像实际存在 getName()、getVersion() 和 getUrl() 方法一样。
这显然要比 Java 语言中的等效方法更加清晰。在 Java 中,必须创建单独的 DriverManager、Connection、Statement 和 JDBCResultSet,然后必须在嵌套的 try/catch/finally 块中将它们全部清除。
对于 Sql 对象,您会认为 each() 或 eachRow() 都是一个合理的方法名。但是在接下来的示例中,我想您会认为 each() 这个名称并不能充分表达它的功能。