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 のループ処理、例外処理に伴うクローズ処理を隠蔽し、コードの可読性と保守性を向上させることができます。