Flyinsky's Codes
1224 字
6 分钟
JDBC
2024-10-20

JDBC 连接与使用详解以及 HikariCP 连接池#

1. 什么是 JDBC?#

JDBC(Java Database Connectivity)是 Java 编程语言中的一项 API,用于连接和执行 SQL 查询数据库。JDBC 提供了标准接口,允许开发者使用 Java 应用程序与不同的数据库系统(如 MySQL、Oracle、PostgreSQL 等)进行交互。

1.1 JDBC 的工作流程#

JDBC 提供了一组接口来简化与数据库的交互,主要步骤包括:

  1. 加载驱动程序:JDBC 需要特定数据库的驱动程序来创建连接。通过类加载机制动态加载驱动类。
  2. 创建连接:使用 DriverManager 类的 getConnection() 方法创建数据库连接。
  3. 创建 Statement 对象:通过 Connection 对象创建 Statement 对象,用于执行 SQL 查询。
  4. 执行查询:使用 StatementPreparedStatement 执行 SQL 查询,并获得结果。
  5. 处理结果:通过 ResultSet 对象处理查询结果。
  6. 关闭资源:关闭 ResultSetStatementConnection 等资源,避免资源泄露。

1.2 使用 JDBC 连接数据库的步骤#

以连接 MySQL 数据库为例,JDBC 连接的常规步骤如下:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JdbcExample {
    public static void main(String[] args) {
        // 数据库 URL, 用户名和密码
        String url = "jdbc:mysql://localhost:3306/mydb";
        String user = "root";
        String password = "password";
        
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        
        try {
            // 1. 加载驱动程序
            Class.forName("com.mysql.cj.jdbc.Driver");

            // 2. 创建数据库连接
            connection = DriverManager.getConnection(url, user, password);

            // 3. 创建 Statement 对象
            statement = connection.createStatement();

            // 4. 执行查询
            String query = "SELECT * FROM users";
            resultSet = statement.executeQuery(query);

            // 5. 处理结果
            while (resultSet.next()) {
                System.out.println("User: " + resultSet.getString("username"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 6. 关闭资源
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

1.3 注意事项#

  • 在实际应用中,务必在使用完数据库连接后及时关闭连接,以避免连接泄漏。
  • 直接使用 DriverManager 创建连接在大型应用中效率较低,因为每次创建和销毁连接都消耗时间和资源。因此,推荐使用连接池来管理数据库连接。

2. HikariCP 连接池介绍#

2.1 什么是连接池?#

连接池(Connection Pool)是为了提高数据库操作的效率,通过提前建立一组数据库连接并管理它们。在应用程序运行时,连接池将提供现有连接,而不是每次都重新创建和销毁连接,从而节省资源并提高性能。

2.2 HikariCP 概述#

HikariCP 是 Java 生态系统中一款非常轻量级且高效的 JDBC 连接池,因其出色的性能和低延迟而广受欢迎。它提供了比其他主流连接池(如 C3P0、Druid 等)更快的连接处理速度和更低的内存消耗。

HikariCP 的优势:#

  1. 高性能:HikariCP 被认为是性能最快的 JDBC 连接池之一,能在最短时间内提供数据库连接。
  2. 轻量级:HikariCP 非常轻量,只有少量的依赖,配置简单。
  3. 稳定性和可靠性:HikariCP 在高负载环境下非常稳定,适合大规模应用。
  4. 快速恢复:在连接中断时,HikariCP 能够快速检测并恢复连接。

2.3 配置 HikariCP#

在 Java 项目中使用 HikariCP 非常简单,只需配置必要的数据库连接信息和一些性能调优参数。下面是一个 HikariCP 的配置示例:

2.3.1 Maven 依赖#

如果你的项目使用 Maven 构建,可以通过添加以下依赖来引入 HikariCP:

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.0.0</version>
</dependency>

2.3.2 HikariCP 配置示例#

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

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class HikariCPExample {
    public static void main(String[] args) {
        // 配置 HikariCP
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(10);  // 最大连接数
        config.setMinimumIdle(2);       // 最小空闲连接数
        config.setConnectionTimeout(30000); // 连接超时

        // 创建连接池
        HikariDataSource dataSource = new HikariDataSource(config);

        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            // 从连接池获取连接
            connection = dataSource.getConnection();

            // 创建 Statement 并执行查询
            statement = connection.createStatement();
            resultSet = statement.executeQuery("SELECT * FROM users");

            // 处理结果集
            while (resultSet.next()) {
                System.out.println("User: " + resultSet.getString("username"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源 (归还连接给连接池)
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 关闭连接池
            dataSource.close();
        }
    }
}

​ 此外,还可以将连接池通过静态方法和静态类的特性封装为一个连接池个工具类,直接向工具类索取连接。

2.4 关键配置参数#

  • maximumPoolSize:最大连接数,指的是连接池中可以同时存在的最大数据库连接数量。
  • minimumIdle:最小空闲连接数,连接池中保持的最少的空闲连接数,超过这个数的连接将被释放。
  • connectionTimeout:等待连接的最大时长,超过该时间将抛出超时异常。
  • idleTimeout:空闲连接的最大存活时间,超过该时间的空闲连接将被关闭。