JDBCによるデータベース連携

2025-08-05

はじめに

JSP/Servletを使用したWebアプリケーション開発において、データベース連携は不可欠な要素です。本記事では、JDBC(Java Database Connectivity)を使用してJavaアプリケーションからデータベースに接続する方法を詳しく解説します。MySQLをメインに説明しますが、他のデータベース(PostgreSQL、Oracleなど)への接続方法も併せて紹介し、JDBCの汎用性を示します。

JDBCの基本概念

JDBCとは

JDBCはJavaアプリケーションからデータベースにアクセスするための標準APIです。以下のような特徴があります:

  • データベース独立: 同じコードで異なるデータベースに接続可能
  • ドライバベース: 各DBベンダーが提供するJDBCドライバを使用
  • SQLベース: SQL文を直接実行できる
jdbc-architecture

JDBCの主要インターフェース

インターフェース説明
DriverManagerデータベース接続を管理
Connectionデータベースとの接続を表す
StatementSQL文を実行する
PreparedStatementパラメータ化されたSQL文を実行
ResultSet問い合わせ結果を保持

MySQLへの接続方法

1. JDBCドライバの準備

MySQLを使用するには、まずJDBCドライバをプロジェクトに追加する必要があります。

Mavenプロジェクトの場合:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
</dependency>

Gradleプロジェクトの場合:

implementation 'mysql:mysql-connector-java:8.0.28'

2. 基本的な接続コード

以下はMySQLに接続する基本的なコード例です。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class MySQLConnectionExample {
    public static void main(String[] args) {
        // JDBC接続情報
        String jdbcUrl = "jdbc:mysql://localhost:3306/mydatabase";
        String username = "root";
        String password = "password";

        try {
            // 1. データベースへの接続
            Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
            System.out.println("MySQLデータベースに接続しました!");

            // 2. ここでデータベース操作を行う

            // 3. 接続を閉じる
            connection.close();
        } catch (SQLException e) {
            System.err.println("データベース接続エラー:");
            e.printStackTrace();
        }
    }
}

3. 接続URLの詳細

MySQLの接続URLにはいくつかのオプションを指定できます:

jdbc:mysql://[ホスト名]:[ポート番号]/[データベース名]?[オプション]

例:

String jdbcUrl = "jdbc:mysql://localhost:3306/employee_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";

他のデータベースへの接続

JDBCの利点は、同じようなコードで異なるデータベースに接続できることです。以下に主要なデータベースの接続例を示します。

PostgreSQLへの接続

// PostgreSQL JDBCドライバの追加 (Maven)
// 
//     org.postgresql
//     postgresql
//     42.3.3
// 

String jdbcUrl = "jdbc:postgresql://localhost:5432/mydatabase";
String username = "postgres";
String password = "password";

Connection connection = DriverManager.getConnection(jdbcUrl, username, password);

Oracle Databaseへの接続

// Oracle JDBCドライバの追加 (Maven)
// 
//     com.oracle.database.jdbc
//     ojdbc8
//     21.5.0.0
// 

String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:ORCL";
String username = "system";
String password = "password";

Connection connection = DriverManager.getConnection(jdbcUrl, username, password);

SQL Serverへの接続

// SQL Server JDBCドライバの追加 (Maven)
// 
//     com.microsoft.sqlserver
//     mssql-jdbc
//     9.4.1.jre11
// 

String jdbcUrl = "jdbc:sqlserver://localhost:1433;databaseName=mydatabase";
String username = "sa";
String password = "password";

Connection connection = DriverManager.getConnection(jdbcUrl, username, password);

データベース操作の基本

接続が確立したら、実際にデータベースを操作してみましょう。

テーブル作成

try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
     Statement stmt = conn.createStatement()) {

    String sql = "CREATE TABLE IF NOT EXISTS employees (" +
                 "id INT AUTO_INCREMENT PRIMARY KEY," +
                 "name VARCHAR(100) NOT NULL," +
                 "email VARCHAR(100) UNIQUE NOT NULL," +
                 "department VARCHAR(50)," +
                 "salary DECIMAL(10,2)" +
                 ")";

    stmt.executeUpdate(sql);
    System.out.println("employeesテーブルが作成されました");
} catch (SQLException e) {
    e.printStackTrace();
}

データの挿入

String insertSQL = "INSERT INTO employees (name, email, department, salary) " +
                  "VALUES ('山田太郎', 'taro@example.com', '営業部', 350000)";

try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
     Statement stmt = conn.createStatement()) {

    int affectedRows = stmt.executeUpdate(insertSQL);
    System.out.println(affectedRows + "行が挿入されました");
} catch (SQLException e) {
    e.printStackTrace();
}

PreparedStatementを使用した安全な挿入

String insertSQL = "INSERT INTO employees (name, email, department, salary) VALUES (?, ?, ?, ?)";

try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
     PreparedStatement pstmt = conn.prepareStatement(insertSQL)) {

    pstmt.setString(1, "鈴木花子");
    pstmt.setString(2, "hanako@example.com");
    pstmt.setString(3, "人事部");
    pstmt.setBigDecimal(4, new BigDecimal(420000));

    int affectedRows = pstmt.executeUpdate();
    System.out.println(affectedRows + "行が挿入されました");
} catch (SQLException e) {
    e.printStackTrace();
}

データの検索

String selectSQL = "SELECT id, name, email, department, salary FROM employees";

try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery(selectSQL)) {

    System.out.println("ID\t名前\tメール\t部署\t給与");
    while (rs.next()) {
        int id = rs.getInt("id");
        String name = rs.getString("name");
        String email = rs.getString("email");
        String department = rs.getString("department");
        BigDecimal salary = rs.getBigDecimal("salary");

        System.out.printf("%d\t%s\t%s\t%s\t%,.2f%n", 
                         id, name, email, department, salary);
    }
} catch (SQLException e) {
    e.printStackTrace();
}

トランザクション管理

複数のSQL操作を1つの単位として扱うトランザクションの例です。

Connection conn = null;
try {
    conn = DriverManager.getConnection(jdbcUrl, username, password);

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

    // 給与の更新
    String updateSQL1 = "UPDATE employees SET salary = salary * 1.1 WHERE department = ?";
    try (PreparedStatement pstmt = conn.prepareStatement(updateSQL1)) {
        pstmt.setString(1, "営業部");
        pstmt.executeUpdate();
    }

    // 部署の変更
    String updateSQL2 = "UPDATE employees SET department = ? WHERE name = ?";
    try (PreparedStatement pstmt = conn.prepareStatement(updateSQL2)) {
        pstmt.setString(1, "マーケティング部");
        pstmt.setString(2, "鈴木花子");
        pstmt.executeUpdate();
    }

    // コミット
    conn.commit();
    System.out.println("トランザクションが正常に完了しました");
} catch (SQLException e) {
    if (conn != null) {
        try {
            conn.rollback();
            System.err.println("トランザクションがロールバックされました");
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
    e.printStackTrace();
} finally {
    if (conn != null) {
        try {
            conn.setAutoCommit(true); // 自動コミットを元に戻す
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

接続プーリングの導入

本番環境では、接続プーリングを使用するのが一般的です。ここではHikariCPという人気のある接続プールライブラリの使用方法を紹介します。

HikariCPの設定

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class ConnectionPoolExample {
    public static void main(String[] args) {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");
        config.setUsername("root");
        config.setPassword("password");
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

        try (HikariDataSource ds = new HikariDataSource(config);
             Connection conn = ds.getConnection()) {

            System.out.println("接続プールから接続を取得しました");

            // データベース操作を行う
            try (Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT 1")) {

                if (rs.next()) {
                    System.out.println("接続テスト成功: " + rs.getInt(1));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

JSP/Servletでの実装例

最後に、JSP/ServletアプリケーションでJDBCを使用する実践的な例を示します。

Servletでのデータアクセス

@WebServlet("/employees")
public class EmployeeServlet extends HttpServlet {
    private DataSource dataSource;

    @Override
    public void init() throws ServletException {
        try {
            // コンテキストからDataSourceを取得 (TomcatなどのJNDIを使用)
            Context ctx = new InitialContext();
            dataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/EmployeeDB");
        } catch (NamingException e) {
            throw new ServletException("データソースの初期化に失敗しました", e);
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {

        List employees = new ArrayList<>();

        try (Connection conn = dataSource.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM employees")) {

            while (rs.next()) {
                Employee emp = new Employee();
                emp.setId(rs.getInt("id"));
                emp.setName(rs.getString("name"));
                emp.setEmail(rs.getString("email"));
                emp.setDepartment(rs.getString("department"));
                emp.setSalary(rs.getBigDecimal("salary"));
                employees.add(emp);
            }

            req.setAttribute("employees", employees);
            req.getRequestDispatcher("/WEB-INF/views/employees.jsp").forward(req, resp);

        } catch (SQLException e) {
            throw new ServletException("データベースアクセスエラー", e);
        }
    }
}

JSPでの表示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
    <title>従業員一覧</title>
    <style>
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>従業員一覧</h1>
    <table>
        <tr>
            <th>ID</th>
            <th>名前</th>
            <th>メール</th>
            <th>部署</th>
            <th>給与</th>
        </tr>
        <c:forEach items="${employees}" var="emp">
            <tr>
                <td>${emp.id}</td>
                <td>${emp.name}</td>
                <td>${emp.email}</td>
                <td>${emp.department}</td>
                <td>${emp.salary}</td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

まとめ

JDBCを使用することで、Javaアプリケーションから様々なデータベースにアクセスできます。本記事では以下の内容を解説しました:

  1. MySQLを中心としたJDBCの基本的な使用方法
  2. 他の主要データベース(PostgreSQL、Oracle、SQL Server)への接続方法
  3. 基本的なCRUD操作の実装
  4. トランザクション管理の方法
  5. 接続プーリングの導入
  6. JSP/Servletアプリケーションでの実践的な実装例

JDBCはデータベース操作の基礎となる技術です。この知識を基に、さらに高度なデータアクセス技術(JPA、MyBatisなど)の学習に進むことができます。