Apache Commons DBUtilsを利用した効率的なJDBCプログラミング

Apache Commons DBUtilsは、JavaにおけるJDBC(Java Database Connectivity)操作を簡略化するための軽量なライブラリです。従来のJDBCプログラミングで発生しがちな冗長なボイラープレートコードを大幅に削減し、開発者がSQLの実装に集中できる環境を提供します。

DBUtilsの主要なコンポーネント

DBUtilsは主に以下の3つのコンポーネントで構成されています。

  • QueryRunner: SQL文を実行するための中心的なクラスです。SELECT、INSERT、UPDATE、DELETEの各操作をサポートするメソッドを提供します。
  • ResultSetHandler: java.sql.ResultSetをJavaオブジェクトやリスト、マップなどの扱いやすい形式に変換するインターフェースです。
  • DbUtils: リソースのクローズ(接続、ステートメント、結果セット)や、トランザクションのロールバックなどを補助する静的メソッド群を提供します。

QueryRunnerによるデータの更新(INSERT / UPDATE / DELETE)

データの追加、更新、削除には QueryRunner.update() メソッドを使用します。このメソッドは実行の影響を受けた行数を返します。


import org.apache.commons.dbutils.QueryRunner;
import java.sql.Connection;
import java.sql.SQLException;

public class MemberRepository {
    
    // データの登録
    public void createMember(Member member) throws SQLException {
        QueryRunner runner = new QueryRunner();
        String sql = "INSERT INTO members (username, password) VALUES (?, ?)";
        
        try (Connection conn = DatabaseConnector.getConnection()) {
            runner.update(conn, sql, member.getName(), member.getPass());
        }
    }

    // データの削除
    public void removeMember(int id) throws SQLException {
        QueryRunner runner = new QueryRunner();
        String sql = "DELETE FROM members WHERE id = ?";
        
        try (Connection conn = DatabaseConnector.getConnection()) {
            runner.update(conn, sql, id);
        }
    }

    // データの更新
    public void modifyMember(Member member) throws SQLException {
        QueryRunner runner = new QueryRunner();
        String sql = "UPDATE members SET username = ?, password = ? WHERE id = ?";
        
        try (Connection conn = DatabaseConnector.getConnection()) {
            runner.update(conn, sql, member.getName(), member.getPass(), member.getId());
        }
    }
}

ResultSetHandlerによるデータの取得

検索クエリの結果をどのように受け取るかは、ResultSetHandlerの実装クラスによって決定されます。DBUtilsには標準的な実装が多数用意されています。

実装クラス 説明
BeanHandler<T> 結果セットの最初の行を特定のJavaBeanオブジェクトに変換します。
BeanListHandler<T> 結果セットの全行をJavaBeanのリスト(List<T>)に変換します。
ArrayHandler 最初の行を Object[] に変換します。
ArrayListHandler 全行を List<Object[]> に変換します。
MapHandler 最初の行を Map<String, Object> に変換します(キーは列名)。
ScalarHandler<T> 集計関数(COUNTなど)の結果など、単一の値を返します。
ColumnListHandler<T> 特定の列の値をリスト形式で抽出します。

クエリ実行の実装例

以下は、DataSourceをコンストラクタに渡して自動的に接続管理を行う場合の検索コード例です。


import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class MemberService {
    private QueryRunner runner = new QueryRunner(DatabaseConnector.getDataSource());

    // 1件取得(BeanHandler)
    public Member findMemberById(int id) throws SQLException {
        String sql = "SELECT * FROM members WHERE id = ?";
        return runner.query(sql, new BeanHandler<>(Member.class), id);
    }

    // 全件取得(BeanListHandler)
    public List<Member> findAllMembers() throws SQLException {
        String sql = "SELECT * FROM members";
        return runner.query(sql, new BeanListHandler<>(Member.class));
    }

    // 行数取得(ScalarHandler)
    public long getMemberCount() throws SQLException {
        String sql = "SELECT COUNT(*) FROM members";
        return runner.query(sql, new ScalarHandler<Long>());
    }

    // 特定カラムのリスト取得(ColumnListHandler)
    public List<String> getAllUsernames() throws SQLException {
        String sql = "SELECT username FROM members";
        return runner.query(sql, new ColumnListHandler<String>());
    }

    // Map形式での取得(MapListHandler)
    public List<Map<String, Object>> getRawMemberData() throws SQLException {
        String sql = "SELECT * FROM members";
        return runner.query(sql, new MapListHandler());
    }
}

DBUtilsを利用することで、従来のJDBCで必要だった PreparedStatement のセットアップや ResultSet のループ処理、例外処理に伴うクローズ処理を隠蔽し、コードの可読性と保守性を向上させることができます。

タグ: Java JDBC Apache Commons DBUtils database

6月8日 16:44 投稿