JDBC入門向けチートシート

データベース接続の基本から応用まで

2025年3月22日

JDBCとは何か?

JDBC (Java Database Connectivity) は、Javaアプリケーションからデータベースにアクセスするための標準APIです。

JDBCを使用すると、データベースの種類に依存せず、一貫した方法でデータの操作が可能になります。

JDBCの主な特徴

  • 異なるデータベースに対する統一的なアクセス方法を提供
  • SQL文を使用したデータ操作をサポート
  • トランザクション管理機能を提供
  • Java SE標準ライブラリに含まれている
JDBCはODBCをベースに設計されていますが、Java固有の機能を多く持っています。

JDBCアーキテクチャ

JDBCの4つの主要コンポーネント

アプリケーション
JDBC API
JDBCドライバ
データベース

JDBCドライバのタイプ

  • Type 1: JDBC-ODBC ブリッジドライバ (非推奨)
  • Type 2: ネイティブAPIドライバ
  • Type 3: ネットワークプロトコルドライバ
  • Type 4: 純粋Javaドライバ(最も推奨
プロジェクトでは通常、Type 4ドライバを使用することをお勧めします。これは純粋なJavaで書かれており、パフォーマンスが最も優れています。

基本的なJDBC操作の流れ

  1. JDBCドライバの登録
  2. データベース接続の確立
  3. Statementオブジェクトの作成
  4. SQLクエリの実行
  5. 結果の処理
  6. リソースのクローズ
// 1. JDBCドライバの登録
Class.forName("com.mysql.cj.jdbc.Driver");

// 2. データベース接続の確立
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/mydb", "username", "password");

// 3. Statementオブジェクトの作成
Statement stmt = conn.createStatement();

// 4. SQLクエリの実行
ResultSet rs = stmt.executeQuery("SELECT * FROM users");

// 5. 結果の処理
while (rs.next()) {
    String name = rs.getString("name");
    int age = rs.getInt("age");
    System.out.println(name + ": " + age);
}

// 6. リソースのクローズ
rs.close();
stmt.close();
conn.close();

JDBCの主要クラスとインターフェース

接続関連

  • DriverManager: データベース接続を管理
  • Connection: データベースへの接続を表現

ステートメント関連

  • Statement: 単純なSQL文を実行
  • PreparedStatement: 事前コンパイルされたSQL文(推奨
  • CallableStatement: ストアドプロシージャ呼び出し用

結果関連

  • ResultSet: クエリ結果を保持するテーブル
  • ResultSetMetaData: 結果セットに関するメタデータ
セキュリティのため、StatementよりもPreparedStatementを使用するべきです。SQLインジェクション攻撃を防ぐことができます。

PreparedStatementの使い方

PreparedStatementを使用すると、パラメータ化されたクエリが使用でき、SQLインジェクション攻撃を防ぎます。

// PreparedStatementの作成
String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);

// パラメータの設定
pstmt.setString(1, "田中太郎"); // 1番目の?にセット
pstmt.setInt(2, 30);         // 2番目の?にセット

// 実行
int rowsAffected = pstmt.executeUpdate();

メリット

  • SQLインジェクション攻撃を防止
  • クエリのパフォーマンスが向上(事前コンパイル)
  • バイナリデータを扱いやすい

トランザクション管理

複数のデータベース操作をひとつの論理的な単位として扱います。

Connection conn = null;
try {
    conn = DriverManager.getConnection(url, user, password);
    
    // 自動コミットを無効化
    conn.setAutoCommit(false);
    
    // トランザクション内の処理
    Statement stmt = conn.createStatement();
    stmt.executeUpdate("UPDATE accounts SET balance = balance - 1000 WHERE id = 1");
    stmt.executeUpdate("UPDATE accounts SET balance = balance + 1000 WHERE id = 2");
    
    // 全ての操作が成功したらコミット
    conn.commit();
} catch (SQLException e) {
    // エラーが発生したらロールバック
    if (conn != null) {
        try {
            conn.rollback();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
    e.printStackTrace();
} finally {
    // リソースの解放
    if (conn != null) {
        try {
            conn.setAutoCommit(true);
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
トランザクションはACID特性(原子性、一貫性、独立性、耐久性)を満たすべきです。

JDBCベストプラクティス

コネクションプール

  • データベース接続の作成コストを削減
  • HikariCP、Apache DBCPなどのライブラリを活用

例外処理

  • try-with-resourcesを使用したリソース管理
  • SQLExceptionを適切に処理

セキュリティ

  • 接続情報を外部設定ファイルに保存
  • SQLインジェクション対策としてPreparedStatementを使用
// try-with-resourcesを使用した例
try (
    Connection conn = DriverManager.getConnection(url, user, password);
    PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?")
) {
    pstmt.setInt(1, userId);
    try (ResultSet rs = pstmt.executeQuery()) {
        while (rs.next()) {
            // 結果の処理
        }
    }
} catch (SQLException e) {
    e.printStackTrace();
}