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()));