JDBC チートシート

Java Database Connectivity クイックリファレンス

JDBCとは?

JDBC(Java Database Connectivity)は、Javaアプリケーションからデータベースへアクセスするための標準API。データベースの種類に依存しない統一的なインターフェースを提供し、CRUD操作、トランザクション管理、バッチ処理などを実現します。

データベース接続 SQL実行 トランザクション

ドライバ読み込みと接続

JDBC 4.0以降はドライバの明示的なロードが不要(自動検出)

// データベース接続
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "username";
String password = "password";

try (Connection conn = DriverManager.getConnection(url, user, password)) {
    // 接続成功
    System.out.println("接続成功");
} catch (SQLException e) {
    e.printStackTrace();
}

try-with-resources で自動クローズ

URL形式: jdbc:[subprotocol]://[host]:[port]/[database]

主要インターフェース

Connection

データベースとの接続を管理

Statement

静的SQL文を実行(PreparedStatementを推奨)

PreparedStatement

パラメータ付きSQL文を実行(SQLインジェクション対策)

ResultSet

SELECT文の結果セットを保持

CRUD操作

SELECT(データ取得)

String sql = "SELECT * FROM users WHERE age > ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setInt(1, 20);

    try (ResultSet rs = pstmt.executeQuery()) {
        while (rs.next()) {
            int id = rs.getInt("id");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            System.out.println(id + ", " + name + ", " + age);
        }
    }
}

INSERT(データ追加)

String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setString(1, "山田太郎");
    pstmt.setInt(2, 25);

    int rowsAffected = pstmt.executeUpdate();
    System.out.println(rowsAffected + "件追加されました");
}

UPDATE(データ更新)

String sql = "UPDATE users SET age = ? WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setInt(1, 30);
    pstmt.setInt(2, 1);

    int rowsAffected = pstmt.executeUpdate();
    System.out.println(rowsAffected + "件更新されました");
}
WHERE句を忘れると全レコードが対象

DELETE(データ削除)

String sql = "DELETE FROM users WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setInt(1, 1);

    int rowsAffected = pstmt.executeUpdate();
    System.out.println(rowsAffected + "件削除されました");
}
削除は元に戻せません!WHERE句を必ず確認

トランザクション管理

デフォルトは自動コミット(autoCommit = true)

Connection conn = null;
try {
    conn = DriverManager.getConnection(url, user, password);

    // 自動コミットを無効化
    conn.setAutoCommit(false);

    // SQL実行
    String sql1 = "INSERT INTO accounts (name, balance) VALUES (?, ?)";
    try (PreparedStatement pstmt = conn.prepareStatement(sql1)) {
        pstmt.setString(1, "口座A");
        pstmt.setInt(2, 1000);
        pstmt.executeUpdate();
    }

    String sql2 = "INSERT INTO accounts (name, balance) VALUES (?, ?)";
    try (PreparedStatement pstmt = conn.prepareStatement(sql2)) {
        pstmt.setString(1, "口座B");
        pstmt.setInt(2, 2000);
        pstmt.executeUpdate();
    }

    // コミット
    conn.commit();
    System.out.println("トランザクション成功");

} catch (SQLException e) {
    // ロールバック
    if (conn != null) {
        try {
            conn.rollback();
            System.out.println("トランザクションをロールバック");
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
    e.printStackTrace();
} finally {
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

主要メソッド

setAutoCommit(false)

自動コミットを無効化

commit()

変更をデータベースに確定

rollback()

変更を取り消して元に戻す

注意: autoCommit=false の状態で接続をクローズすると、未コミットの変更は失われます

バッチ処理

複数のSQL文をまとめて実行することでパフォーマンス向上

String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    // バッチに追加
    pstmt.setString(1, "山田太郎");
    pstmt.setInt(2, 25);
    pstmt.addBatch();

    pstmt.setString(1, "佐藤花子");
    pstmt.setInt(2, 30);
    pstmt.addBatch();

    pstmt.setString(1, "鈴木一郎");
    pstmt.setInt(2, 28);
    pstmt.addBatch();

    // バッチ実行
    int[] results = pstmt.executeBatch();
    System.out.println(results.length + "件のバッチ処理が完了");
}

addBatch()

バッチにSQL文を追加

executeBatch()

バッチ内の全SQL文を実行

clearBatch()

バッチをクリア

例外処理(SQLException)

try {
    // JDBC処理
    Connection conn = DriverManager.getConnection(url, user, password);
    // ...
} catch (SQLException e) {
    System.err.println("SQLエラー: " + e.getMessage());
    System.err.println("SQLState: " + e.getSQLState());
    System.err.println("ErrorCode: " + e.getErrorCode());
    e.printStackTrace();
}

SQLExceptionのメソッド

getMessage()

エラーメッセージを取得

getSQLState()

SQLStateコードを取得

getErrorCode()

ベンダー固有のエラーコードを取得

実務で役立つTips

SQLインジェクション対策

必ずPreparedStatementを使用し、文字列結合でSQLを組み立てない

リソース管理

try-with-resourcesを使ってConnection、Statement、ResultSetを確実にクローズ

接続プール

実運用ではHikariCP等の接続プールライブラリを使用してパフォーマンス向上

NULL値の処理

ResultSet.wasNull()でNULL判定を行う(getString等はnullを返す)

JDBC実行フロー

1 ドライバロード
2 接続確立
3 SQL実行
4 結果処理
5 リソース解放

try-with-resourcesを使えばステップ5は自動実行

よく使うパターン

単一レコード取得

String sql = "SELECT * FROM users WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setInt(1, userId);

    try (ResultSet rs = pstmt.executeQuery()) {
        if (rs.next()) {
            // レコードが存在
            String name = rs.getString("name");
            int age = rs.getInt("age");
            // 処理...
        } else {
            // レコードが存在しない
            System.out.println("ユーザーが見つかりません");
        }
    }
}

接続プール使用例(HikariCP)

// HikariCPの設定
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("username");
config.setPassword("password");
config.setMaximumPoolSize(10);

HikariDataSource dataSource = new HikariDataSource(config);

// 接続取得(プールから)
try (Connection conn = dataSource.getConnection()) {
    // SQL実行
}

自動生成キーの取得

String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql,
        Statement.RETURN_GENERATED_KEYS)) {
    pstmt.setString(1, "山田太郎");
    pstmt.setInt(2, 25);
    pstmt.executeUpdate();

    // 自動生成されたIDを取得
    try (ResultSet rs = pstmt.getGeneratedKeys()) {
        if (rs.next()) {
            int generatedId = rs.getInt(1);
            System.out.println("生成されたID: " + generatedId);
        }
    }
}

メタデータ取得

// データベースメタデータ
DatabaseMetaData metaData = conn.getMetaData();
String dbName = metaData.getDatabaseProductName();
String dbVersion = metaData.getDatabaseProductVersion();

// ResultSetメタデータ
ResultSet rs = pstmt.executeQuery();
ResultSetMetaData rsMetaData = rs.getMetaData();
int columnCount = rsMetaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
    String columnName = rsMetaData.getColumnName(i);
    String columnType = rsMetaData.getColumnTypeName(i);
}