groovyのSqlでjava.sql.StatementのsetMaxRowsしたい場合 2007/08/21

java.sql.Statementには、setMaxRowsというメソッドが用意されています。

この Statement オブジェクトで作成された任意の ResultSet オブジェクトが含むことのできる最大行数の制限値を、指定された数に設定します。制限値を超えた行は通知なしに除外されます。
java6 doc api


つまり、ResultSetで指定したサイズ以上のデータをもらいませんよ、ということですね。

ところで、groovyのSQLはすんごい便利そうですね。
groovyでSQLしたい場合は、groovyのほうで用意してくれている、Sqlクラスを使用しますが、Sql.newInstanceで生成したこのsqlオブジェクトからどうやってjava.sql.StatementのsetMaxRowsみたいなことするのというはなしですが、えーと、ここでやはり登場するのがクロージャーというわけです。

groovy.sql.SqlにはwithStatementというメソッドが用意されているんですね。教えてもらってなるほどと思った次第なのですが、このメソッドは引数に、Closureオブジェクトをもらいます。

apidocには下記のように記されています。
Allows a closure to be passed in to configure the JDBC statements before they are executed to do things like set the query size etc.
javadoc groovy api

ほーほーなるほどなるほど。

で、JDBC statementが実行される前によばれるよとあります。ってどういうふうに使うのよ、と、この手の言語になれていないと思うわけです。

それで、groovy.sql.Sqlをみてみますと、
0990 /**
0991 * Allows a closure to be passed in to configure the JDBC statements before they are executed
0992 * to do things like set the query size etc.
0993 *
0994 * @param configureStatement
0995 */
0996 public void withStatement(Closure configureStatement) {
0997 this.configureStatement = configureStatement;
0998 }


とあります。

そして、このconfigureStatementがどこで実行されるのかといいますと、protectedメソッドのconfigureで実行されるわけです。もちろんこのconfigureメソッドは、Sqlオブジェクトを操作する人からは直接操作できません。

1252 /**
1253 * Provides a hook to be able to configure JDBC statements, such as to configure
1254 *
1255 * @param statement
1256 */
1257 protected void configure(Statement statement) {
1258 if (configureStatement != null) {
1259 configureStatement.call(statement);
1260 }
1261 }


すんごく感心してしまったんです。
Statementをクロージャに渡してくれるんですね。で、そのStatementを操作するわけです。


肝心の、StatementへのsetMaxRows設定は、
sql.withStatement({statement -> statement.setMaxRows(1000)})

という感じにするんですよね。

さらにgroovyおもしろいなぁと思ったんだですが、何がそんなにおもしろいと思ったのか伝わりましたでしょうか。いやそれとも、こんなの常識!?

参考
Sql Groovy 1.0.jsr06 API Documentation and Javadoc
IBM 実用的なGroovy: GroovyによるJDBCプログラミング - Japan

: