JDBC - 连接池



对于流量很大的网站,获取数据库连接的资源可能非常昂贵。此外,想象一下,一个网站有 500 个并发用户,每个用户都试图获取一个连接来选择或更新数据。在这种情况下,为了防止多个用户破坏数据,数据库会使用锁。当一个用户对一个表进行选择操作时,该表会被锁定。除非释放锁,否则其他用户无法获取该表。让 500 个用户等待连接是不可接受的。

Java 中的连接池是一种用于提高数据库驱动应用程序性能的技术。与其每次应用程序需要与数据库交互时都创建一个新的连接,不如创建一个连接池,并由连接池管理器进行管理。这消除了每次建立新连接的开销,从而导致更快的响应时间和更好的资源利用率。

连接池的优点

以下是连接池的优点。

  • 性能提升 - 连接池减少了创建和关闭连接的开销,从而使应用程序的响应时间更快。

  • 资源优化 - 通过重用连接,连接池有助于节省系统资源,例如内存和网络连接。

  • 可扩展性 - 连接池可以根据需求动态增长或缩小,允许您的应用程序处理不同的工作负载。

流行的连接池库

以下是流行的连接池库。

  • HikariCP - 以其性能和效率而闻名。

  • Apache Commons DBCP - 使用广泛且久负盛名。

  • c3p0 - 另一个流行的选择,专注于稳定性。

示例:使用 HikariCP 的连接池

我们将使用 HikariCP 连接池库。在 Eclipse 中,转到文件 -> 新建 -> Java 项目

将项目的名称设置为HikariCPExample。单击完成。现在在项目资源管理器中,右键单击项目名称,选择构建路径 -> 添加外部存档。添加以下 3 个 jar 包

  1. HikariCP-5.0.1.jar - 从 HikariCP-5.0.1.jar 下载

  2. mysql-connector-j-8.4.0.jar - 从 mysql-connector-j-8.4.0.jar 下载

  3. slf4j-api-2.1.0-alpha1.jar - 从 slf4j-api-2.1.0-alpha1.jar 下载

在 Eclipse 中,单击菜单文件 -> 新建类以创建一个新类。将文件命名为HikariCPManager。不要为包名填写任何内容。单击完成

在 Eclipse 中,单击文件 -> 新建类。将文件命名为TestPooledConnection。不要填写任何包名。单击<完成>。

HikariCPManager.java

我们创建了一个 HikariConfig() 实例并设置了 JDBC url、用户名和密码。最大池大小设置为 10。getPooledConnection() 方法用于获取数据库连接。

import java.sql.Connection;
import java.sql.SQLException;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class HikariCPManager {
   public static HikariDataSource dataSource;
   public  static HikariConfig config = null;
   // Set properties in constructor
   HikariCPManager(){
      config = new HikariConfig();
      config.setJdbcUrl("jdbc:mysql://127.0.0.1/TUTORIALSPOINT");
      config.setUsername("root");
      config.setPassword("guest123");
      // Set maximum connection pool size
      config.setMaximumPoolSize(10); 
      dataSource = new HikariDataSource(config);
   }

   public static Connection getPooledConnection() throws SQLException {
      return dataSource.getConnection();
   }

   public static void close () {
      if (dataSource != null) {
         dataSource.close();
      }
   }
}

TestPooledConnection.java

在这个例子中,我们创建了 HikariCPManager 实例,并使用 getPooledConnection() 准备了一个池化连接。一旦连接对象准备就绪,我们就使用 SELECT 查询准备了一个 PreparedStatement 实例。使用 executeQuery() 执行查询,并通过迭代接收到的 resultSet 打印所有员工。

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestPooledConnection {
   public static void main(String[] args) {
      Connection conn = null;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      try {
         HikariCPManager hcpm = new HikariCPManager();
         conn = hcpm.getPooledConnection();

         if (conn != null) {
            // Prepare statement
            String sql = "SELECT * FROM employees";
            pstmt = conn.prepareStatement(sql);

            // Execute query
            rs = pstmt.executeQuery();

            // Process and print results
            while (rs.next()) {
               int id = rs.getInt("id");
               String fname = rs.getString("first");
               String lname = rs.getString("last");
               System.out.println("ID: " + id + ", First Name: " + fname + ",  Last Name:  " + lname);
            }
         } else {
            System.out.println("Error getting connection.");
         }
      } catch (SQLException e) {
         e.printStackTrace();
      } finally {
         // Close all resources
         try {
            if (rs != null) rs.close();
               if (pstmt != null) pstmt.close();
                  if (conn != null) conn.close();
         } catch (SQLException e) {
            e.printStackTrace();
         }
      }
      // Close connection pool
      HikariCPManager.close();
   }
}

输出

在 Eclipse 中,在包资源管理器上,右键单击 TestPooledConnection.java,转到以 Java 应用程序方式运行 -> 运行。在控制台上,您将看到 -

ID: 1, First Name: Shahbaz,  Last Name:  Ali
ID: 2, First Name: Mahnaz,  Last Name:  Fatma
ID: 4, First Name: Sumit,  Last Name:  Mittal
ID: 21, First Name: Jeevan,  Last Name:  Rao
ID: 22, First Name: Dinesh,  Last Name:  Kumar
ID: 25, First Name: Jeevan,  Last Name:  Rao
ID: 26, First Name: Aditya,  Last Name:  Chaube
ID: 34, First Name: Ahmed,  Last Name:  Ali
ID: 35, First Name: Raksha,  Last Name:  Agarwal
广告