Java Database Connectivity
はじめに
[編集]Java Database Connectivity(JDBC)は、Javaアプリケーションがリレーショナルデータベースと対話するための標準APIです。JDBCを使用することで、開発者はデータベースへの接続、SQLクエリの実行、結果の取得などを行うことができます。本ハンドブックでは、JDBCの基本的な概念から応用的な使い方までを解説し、実際のコード例や表を交えながら理解を深めていきます。
第1章 JDBCの基本
[編集]1.1 JDBCの概要
[編集]JDBCは、Javaアプリケーションとデータベース間の橋渡し役を果たします。JDBC APIは、データベースベンダーが提供するJDBCドライバを介して、特定のデータベースと通信します。JDBCドライバは、Javaアプリケーションからのリクエストをデータベースが理解できる形式に変換し、その結果をJavaアプリケーションに返します。
1.2 JDBCアーキテクチャ
[編集]JDBCアーキテクチャは、主に以下のコンポーネントで構成されています。
- JDBC API: Javaアプリケーションがデータベースと対話するためのインターフェースを提供します。
- JDBC Driver Manager: アプリケーションと適切なJDBCドライバを接続します。
- JDBC Driver: データベースベンダーが提供するドライバで、Javaアプリケーションとデータベース間の通信を実現します。
- データベース: 実際のデータを格納するリレーショナルデータベース。
1.3 JDBCドライバの種類
[編集]JDBCドライバには、以下の4つのタイプがあります。
- タイプ1: JDBC-ODBCブリッジドライバ
- タイプ2: ネイティブAPIドライバ
- タイプ3: ネットワークプロトコルドライバ
- タイプ4: ネイティブプロトコルドライバ
現在では、タイプ4のドライバが最も一般的に使用されています。これは、純粋なJavaで実装されており、データベースと直接通信するため、パフォーマンスが高いからです。
第2章 JDBCの基本的な使い方
[編集]2.1 データベースへの接続
[編集]JDBCを使用してデータベースに接続するためには、まず適切なJDBCドライバをロードし、Connection
オブジェクトを取得する必要があります。以下は、MySQLデータベースに接続する例です。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class JDBCExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; try { // JDBCドライバをロード Class.forName("com.mysql.cj.jdbc.Driver"); // データベースに接続 Connection connection = DriverManager.getConnection(url, username, password); System.out.println("データベースに接続しました。"); // 接続を閉じる connection.close(); } catch (ClassNotFoundException e) { System.out.println("JDBCドライバが見つかりませんでした。"); e.printStackTrace(); } catch (SQLException e) { System.out.println("データベース接続中にエラーが発生しました。"); e.printStackTrace(); } } }
2.2 SQLクエリの実行
[編集]データベースに接続したら、SQLクエリを実行することができます。以下は、Statement
オブジェクトを使用してSQLクエリを実行する例です。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBCQueryExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; try { // JDBCドライバをロード Class.forName("com.mysql.cj.jdbc.Driver"); // データベースに接続 Connection connection = DriverManager.getConnection(url, username, password); // Statementオブジェクトを作成 Statement statement = connection.createStatement(); // SQLクエリを実行 String sql = "SELECT id, name, age FROM users"; ResultSet resultSet = statement.executeQuery(sql); // 結果を処理 while (resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age); } // リソースを解放 resultSet.close(); statement.close(); connection.close(); } catch (ClassNotFoundException e) { System.out.println("JDBCドライバが見つかりませんでした。"); e.printStackTrace(); } catch (SQLException e) { System.out.println("データベース操作中にエラーが発生しました。"); e.printStackTrace(); } } }
2.3 プリペアドステートメントの使用
[編集]プリペアドステートメントは、SQLインジェクションを防ぐために使用されます。以下は、プリペアドステートメントを使用してデータを挿入する例です。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class JDBCPreparedStatementExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; try { // JDBCドライバをロード Class.forName("com.mysql.cj.jdbc.Driver"); // データベースに接続 Connection connection = DriverManager.getConnection(url, username, password); // プリペアドステートメントを作成 String sql = "INSERT INTO users (name, age) VALUES (?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); // パラメータを設定 preparedStatement.setString(1, "John Doe"); preparedStatement.setInt(2, 30); // SQLクエリを実行 int rowsInserted = preparedStatement.executeUpdate(); System.out.println(rowsInserted + "行が挿入されました。"); // リソースを解放 preparedStatement.close(); connection.close(); } catch (ClassNotFoundException e) { System.out.println("JDBCドライバが見つかりませんでした。"); e.printStackTrace(); } catch (SQLException e) { System.out.println("データベース操作中にエラーが発生しました。"); e.printStackTrace(); } } }
第3章 トランザクション管理
[編集]3.1 トランザクションの基本
[編集]トランザクションは、複数のSQL操作を1つの単位として扱うための仕組みです。トランザクションを使用することで、すべての操作が成功した場合にのみ変更をコミットし、いずれかの操作が失敗した場合にはロールバックすることができます。
3.2 トランザクションの使用例
[編集]以下は、トランザクションを使用して複数のSQL操作を実行する例です。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class JDBCTransactionExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; Connection connection = null; try { // JDBCドライバをロード Class.forName("com.mysql.cj.jdbc.Driver"); // データベースに接続 connection = DriverManager.getConnection(url, username, password); // 自動コミットを無効にする connection.setAutoCommit(false); // プリペアドステートメントを作成 String sql1 = "INSERT INTO users (name, age) VALUES (?, ?)"; PreparedStatement preparedStatement1 = connection.prepareStatement(sql1); preparedStatement1.setString(1, "Alice"); preparedStatement1.setInt(2, 25); preparedStatement1.executeUpdate(); String sql2 = "UPDATE users SET age = ? WHERE name = ?"; PreparedStatement preparedStatement2 = connection.prepareStatement(sql2); preparedStatement2.setInt(1, 26); preparedStatement2.setString(2, "Alice"); preparedStatement2.executeUpdate(); // トランザクションをコミット connection.commit(); System.out.println("トランザクションがコミットされました。"); // リソースを解放 preparedStatement1.close(); preparedStatement2.close(); } catch (ClassNotFoundException e) { System.out.println("JDBCドライバが見つかりませんでした。"); e.printStackTrace(); } catch (SQLException e) { System.out.println("トランザクション中にエラーが発生しました。ロールバックします。"); try { if (connection != null) { connection.rollback(); } } catch (SQLException ex) { ex.printStackTrace(); } e.printStackTrace(); } finally { try { if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } } } }
第4章 高度なJDBC機能
[編集]4.1 バッチ処理
[編集]バッチ処理を使用すると、複数のSQLクエリを一度に実行することができます。これにより、データベースとの通信回数を減らし、パフォーマンスを向上させることができます。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class JDBCBatchExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; try { // JDBCドライバをロード Class.forName("com.mysql.cj.jdbc.Driver"); // データベースに接続 Connection connection = DriverManager.getConnection(url, username, password); // プリペアドステートメントを作成 String sql = "INSERT INTO users (name, age) VALUES (?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); // バッチにクエリを追加 preparedStatement.setString(1, "Bob"); preparedStatement.setInt(2, 28); preparedStatement.addBatch(); preparedStatement.setString(1, "Charlie"); preparedStatement.setInt(2, 22); preparedStatement.addBatch(); // バッチを実行 int[] rowsInserted = preparedStatement.executeBatch(); System.out.println(rowsInserted.length + "行が挿入されました。"); // リソースを解放 preparedStatement.close(); connection.close(); } catch (ClassNotFoundException e) { System.out.println("JDBCドライバが見つかりませんでした。"); e.printStackTrace(); } catch (SQLException e) { System.out.println("バッチ処理中にエラーが発生しました。"); e.printStackTrace(); } } }
4.2 ストアドプロシージャの呼び出し
[編集]ストアドプロシージャは、データベースに保存された一連のSQLステートメントです。JDBCを使用してストアドプロシージャを呼び出すことができます。
import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class JDBCCallableStatementExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; try { // JDBCドライバをロード Class.forName("com.mysql.cj.jdbc.Driver"); // データベースに接続 Connection connection = DriverManager.getConnection(url, username, password); // ストアドプロシージャを呼び出す String sql = "{call get_user_age(?, ?)}"; CallableStatement callableStatement = connection.prepareCall(sql); // パラメータを設定 callableStatement.setString(1, "Alice"); callableStatement.registerOutParameter(2, java.sql.Types.INTEGER); // ストアドプロシージャを実行 callableStatement.execute(); // 結果を取得 int age = callableStatement.getInt(2); System.out.println("Aliceの年齢は " + age + " 歳です。"); // リソースを解放 callableStatement.close(); connection.close(); } catch (ClassNotFoundException e) { System.out.println("JDBCドライバが見つかりませんでした。"); e.printStackTrace(); } catch (SQLException e) { System.out.println("ストアドプロシージャの呼び出し中にエラーが発生しました。"); e.printStackTrace(); } } }
第5章 JDBCのベストプラクティス
[編集]5.1 リソースの解放
[編集]JDBCを使用する際には、Connection
、Statement
、ResultSet
などのリソースを適切に解放することが重要です。リソースが解放されないと、メモリリークやデータベース接続の枯渇を引き起こす可能性があります。try-with-resources
構文を使用することで、リソースの解放を自動化することができます。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class JDBCResourceExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; try (Connection connection = DriverManager.getConnection(url, username, password); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT id, name, age FROM users")) { while (resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age); } } catch (SQLException e) { System.out.println("データベース操作中にエラーが発生しました。"); e.printStackTrace(); } } }
5.2 接続プーリング
[編集]データベース接続の作成と破棄はコストが高い操作です。接続プーリングを使用することで、接続を再利用し、アプリケーションのパフォーマンスを向上させることができます。HikariCP
やApache DBCP
などのライブラリを使用して、接続プーリングを実装することができます。
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import java.sql.Connection; import java.sql.SQLException; public class JDBCConnectionPoolExample { public static void main(String[] args) { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase"); config.setUsername("root"); config.setPassword("password"); try (HikariDataSource dataSource = new HikariDataSource(config); Connection connection = dataSource.getConnection()) { System.out.println("データベースに接続しました。"); // データベース操作を行う } catch (SQLException e) { System.out.println("データベース接続中にエラーが発生しました。"); e.printStackTrace(); } } }
おわりに
[編集]本ハンドブックでは、JDBCの基本的な使い方から高度な機能までを解説しました。JDBCは、Javaアプリケーションとデータベース間の通信を実現するための強力なツールです。適切に使用することで、効率的で安全なデータベース操作を行うことができます。今後の開発において、本ハンドブックが役立つことを願っています。