JDBCの基礎概念
データベース連携を実装する際、JDBC(Java Database Connectivity)はJavaアプリケーションとリレーショナルデータベース間の標準インタフェースです。このAPIはSQL文の実行を可能にし、データベースベンダーが実装するドライバを通じて動作します。
基本操作フロー
- ドライバ導入: プロジェクトにデータベース固有のJDBCドライバを追加
- ドライバ登録: DriverManagerに使用するデータベースドライバを登録
- 接続確立: データベースへの接続オブジェクトを生成
- 操作実行: SQLクエリや更新処理の実施
- 結果処理: クエリ結果セットまたは更新件数の取得
- リソース解放: 接続やステートメントのクローズ処理
Statementによるデータ操作
静的SQL文を実行する際に使用します。以下はユーザーデータ取得の実装例です。
<!-- pom.xml依存関係 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>import java.sql.*;
public class JdbcStatementExample {
public static void main(String[] args) {
Connection dbConnection = null;
Statement sqlStatement = null;
ResultSet queryResult = null;
try {
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
dbConnection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sampledb?useSSL=false",
"dbuser", "password"
);
sqlStatement = dbConnection.createStatement();
queryResult = sqlStatement.executeQuery("SELECT * FROM user_account");
while(queryResult.next()) {
System.out.println(
"ユーザー名:" + queryResult.getString("user_name") +
" 年齢:" + queryResult.getInt("age") +
" 残高:" + queryResult.getDouble("balance")
);
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
if(queryResult != null) queryResult.close();
if(sqlStatement != null) sqlStatement.close();
if(dbConnection != null) dbConnection.close();
} catch(SQLException ex) {
ex.printStackTrace();
}
}
}
}PreparedStatementによる安全な操作
パラメータ化クエリを使用することでSQLインジェクションを防止します。自動生成キーの取得例:
public class PreparedStatementExample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet keys = null;
try {
// 接続処理(省略)
String insertSQL = "INSERT INTO user_account (user_name, age, balance) VALUES (?, ?, ?)";
pstmt = conn.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, "新規ユーザー");
pstmt.setInt(2, 30);
pstmt.setDouble(3, 500.0);
int affectedRows = pstmt.executeUpdate();
if(affectedRows > 0) {
keys = pstmt.getGeneratedKeys();
if(keys.next()) {
System.out.println("生成ID: " + keys.getInt(1));
}
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
// リソース解放(省略)
}
}
}ストアドプロシージャの実行
CallableStatementを使用したストアドプロシージャ呼び出しの例:
public class StoredProcedureExample {
public static void main(String[] args) {
Connection conn = null;
CallableStatement cstmt = null;
ResultSet rs = null;
try {
// 接続処理(省略)
cstmt = conn.prepareCall("{call get_users_by_age(?, ?)}");
cstmt.setInt(1, 25);
cstmt.registerOutParameter(2, Types.INTEGER);
rs = cstmt.executeQuery();
while(rs.next()) {
// 結果処理
}
System.out.println("該当件数: " + cstmt.getInt(2));
} catch(SQLException e) {
e.printStackTrace();
} finally {
// リソース解放(省略)
}
}
}バッチ処理の最適化
複数の更新処理をまとめて実行する手法:
public class BatchProcessingExample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 接続処理(省略)
String sql = "INSERT INTO user_account (user_name, age, balance) VALUES (?, ?, ?)";
pstmt = conn.prepareStatement(sql);
for(int i=0; i<100; i++) {
pstmt.setString(1, "ユーザー" + i);
pstmt.setInt(2, 20 + i);
pstmt.setDouble(3, 1000.0 + i);
pstmt.addBatch();
}
int[] results = pstmt.executeBatch();
System.out.println("処理件数: " + results.length);
} catch(SQLException e) {
e.printStackTrace();
} finally {
// リソース解放(省略)
}
}
}トランザクション管理
ACID特性を保証する取引処理の実装:
public class TransactionExample {
public static void main(String[] args) {
Connection conn = null;
try {
// 接続処理(省略)
conn.setAutoCommit(false);
// 送金処理1: 口座Aから200円引き落とし
// 送金処理2: 口座Bに200円入金
conn.commit();
} catch(Exception e) {
try {
if(conn != null) conn.rollback();
} catch(SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
// リソース解放(省略)
}
}
}