DbUtilsでアンダーバーを含むカラムをしっぽりとオブジェクトにマッピングする
山根さんのページをみながらDbUtilsを使ってみました。DbUtilsシンプルなのにかなり使えるツールで、SQLを直接発行するほとんどの場面で役に立ちそうです。
DbUtilsではカラム名とJavaオブジェクトのプロパティ名を使って、自動的にマッピングします。デフォルトのマッピングルールはBasicRowProcessorです。
しかし、BasicRowProcessorはカラム名のアンダーバーをそのままオブジェクトのプロパティ名として、マッピングしてしまいます。
例:カラム名BOOK_NAME -> プロパティのセッターメソッド名setBook_Name
これって実は結構使いにくくて、アンダーバーを取り除いて、プロパティ名としてくれれば、嬉しい限り。普通メソッド名にアンダーバーって使わないですしね。
例:カラム名BOOK_NAME -> プロパティのセッターメソッド名setBookName
RowProcessorはインターフェイスなので、SQLの発行時に別のRowProcessorを指定すれば、マッピングのルールを切り替えることができます。
BasicRowProcessorをちょっとオーバライドすれば、いけるかな??と思ってソースを見てみると、カラム名とプロパティ名を比較しているメソッドがprivateになっていて、オーバライドできません。
せめて、protectedだったら・・とうらめしく思いつつ、ソースコピーして、別のクラスを作って修正してなんとか解決。ソースコピーってなんとなく罪悪感を感じちゃいますね。修正っていっても1行追加しただけです。
public class JoinedRowProcessor...
private int mapColumnsToProperties(
ResultSetMetaData rsmd,
PropertyDescriptor props)
throws SQLException {
int cols = rsmd.getColumnCount();
int columnToProperty[] = new int[cols + 1];
for (int col = 1; col <= cols; col++) {
String columnName = rsmd.getColumnName(col);
// ↓この行を追加
columnName = StringUtils.replace(columnName, "_", "");
for (int i = 0; i < props.length; i++) {
// 省略
で、SQLを発行するときにResultSetHandlerにRowProcessorを渡してやればOK!
(JoinedRowProcessorが新しく作ったRowProcessorクラス)
QueryRunner runner = new QueryRunner(dataSource); List result = (List)runner.query( "select * from books", new BeanListHandler(Book.class, JoinedRowProcessor.instance()));