热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入理解JavaMySQL数据库连接池实现

尽管利用ApacheCommonsDBCP等工具可以轻松构建数据库连接池,但本文详细解析了数据库连接池的工作机制,提供了详尽的注释,帮助开发者深入理解其内部运作。这不仅有助于提高数据库操作的效率,还能增强应用程序的稳定性和性能。

尽管通过Apache Commons DBCP等工具可以轻松构建数据库连接池,但深入理解其工作原理对于优化数据库操作和提升应用性能至关重要。本文将详细介绍如何手动实现一个简单的数据库连接池,并提供详细的注释,帮助开发者更好地理解和应用这一技术。

以下是Java中实现MySQL数据库连接池的一个示例代码:

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.Vector;

public class CustomConnectionPool {
private String jdbcDriver = ""; // 数据库驱动
private String dbUrl = ""; // 数据库URL
private String dbUsername = ""; // 数据库用户名
private String dbPassword = ""; // 数据库用户密码
private String testTable = ""; // 测试连接是否可用的表名,默认为空
private int initialCOnnections= 10; // 连接池的初始大小
private int incrementalCOnnections= 5; // 连接池自动增加的大小
private int maxCOnnections= 50; // 连接池最大大小
private Vector cOnnections= null; // 存放连接池中数据库连接的向量,初始为null

public CustomConnectionPool(String jdbcDriver, String dbUrl, String dbUsername, String dbPassword) {
this.jdbcDriver = jdbcDriver;
this.dbUrl = dbUrl;
this.dbUsername = dbUsername;
this.dbPassword = dbPassword;
}

public int getInitialConnections() {
return this.initialConnections;
}

public void setInitialConnections(int initialConnections) {
this.initialCOnnections= initialConnections;
}

public int getIncrementalConnections() {
return this.incrementalConnections;
}

public void setIncrementalConnections(int incrementalConnections) {
this.incrementalCOnnections= incrementalConnections;
}

public int getMaxConnections() {
return this.maxConnections;
}

public void setMaxConnections(int maxConnections) {
this.maxCOnnections= maxConnections;
}

public String getTestTable() {
return this.testTable;
}

public void setTestTable(String testTable) {
this.testTable = testTable;
}

public synchronized void createPool() throws Exception {
if (connections != null) {
return;
}
Class.forName(jdbcDriver).newInstance();
DriverManager.registerDriver((Driver) Class.forName(jdbcDriver).newInstance());
cOnnections= new Vector<>();
createConnections(initialConnections);
System.out.println("数据库连接池创建成功!");
}

@SuppressWarnings("unchecked")
private void createConnections(int numConnections) throws SQLException {
for (int i = 0; i if (maxConnections > 0 && connections.size() >= maxConnections) {
break;
}
try {
connections.add(new PooledConnection(newConnection()));
} catch (SQLException e) {
System.out.println("创建数据库连接失败!" + e.getMessage());
throw new SQLException();
}
System.out.println("数据库连接已创建......");
}
}

private Connection newConnection() throws SQLException {
Connection cOnn= DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
if (connections.size() == 0) {
DatabaseMetaData metaData = conn.getMetaData();
int driverMaxCOnnections= metaData.getMaxConnections();
if (driverMaxConnections > 0 && maxConnections > driverMaxConnections) {
maxCOnnections= driverMaxConnections;
}
}
return conn;
}

public synchronized Connection getConnection() throws SQLException {
if (cOnnections== null) {
return null;
}
Connection cOnn= getFreeConnection();
while (cOnn== null) {
wait(250);
cOnn= getFreeConnection();
}
return conn;
}

private Connection getFreeConnection() throws SQLException {
Connection cOnn= findFreeConnection();
if (cOnn== null) {
createConnections(incrementalConnections);
cOnn= findFreeConnection();
if (cOnn== null) {
return null;
}
}
return conn;
}

private Connection findFreeConnection() throws SQLException {
Connection cOnn= null;
PooledConnection pCOnn= null;
Enumeration enumerate = connections.elements();
while (enumerate.hasMoreElements()) {
pCOnn= enumerate.nextElement();
if (!pConn.isBusy()) {
cOnn= pConn.getConnection();
pConn.setBusy(true);
if (!testConnection(conn)) {
try {
cOnn= newConnection();
} catch (SQLException e) {
System.out.println("创建数据库连接失败!" + e.getMessage());
return null;
}
pConn.setConnection(conn);
}
break;
}
}
return conn;
}

private boolean testConnection(Connection conn) {
try {
if (testTable.isEmpty()) {
conn.setAutoCommit(true);
} else {
Statement stmt = conn.createStatement();
stmt.execute("SELECT COUNT(*) FROM " + testTable);
}
} catch (SQLException e) {
closeConnection(conn);
return false;
}
return true;
}

public void returnConnection(Connection conn) {
if (cOnnections== null) {
System.out.println("连接池不存在,无法返回此连接到连接池中!");
return;
}
PooledConnection pCOnn= null;
Enumeration enumerate = connections.elements();
while (enumerate.hasMoreElements()) {
pCOnn= enumerate.nextElement();
if (cOnn== pConn.getConnection()) {
pConn.setBusy(false);
break;
}
}
}

public synchronized void refreshConnections() throws SQLException {
if (cOnnections== null) {
System.out.println("连接池不存在,无法刷新!");
return;
}
PooledConnection pCOnn= null;
Enumeration enumerate = connections.elements();
while (enumerate.hasMoreElements()) {
pCOnn= enumerate.nextElement();
if (pConn.isBusy()) {
wait(5000);
}
closeConnection(pConn.getConnection());
pConn.setConnection(newConnection());
pConn.setBusy(false);
}
}

public synchronized void closeConnectionPool() throws SQLException {
if (cOnnections== null) {
System.out.println("连接池不存在,无法关闭!");
return;
}
PooledConnection pCOnn= null;
Enumeration enumerate = connections.elements();
while (enumerate.hasMoreElements()) {
pCOnn= enumerate.nextElement();
if (pConn.isBusy()) {
wait(5000);
}
closeConnection(pConn.getConnection());
connections.remove(pConn);
}
cOnnections= null;
}

private void closeConnection(Connection conn) {
try {
conn.close();
} catch (SQLException e) {
System.out.println("关闭数据库连接出错:" + e.getMessage());
}
}

private void wait(int mSeconds) {
try {
Thread.sleep(mSeconds);
} catch (InterruptedException e) {}
}

class PooledConnection {
Connection cOnnection= null;
boolean busy = false;

public PooledConnection(Connection connection) {
this.cOnnection= connection;
}

public Connection getConnection() {
return connection;
}

public void setConnection(Connection connection) {
this.cOnnection= connection;
}

public boolean isBusy() {
return busy;
}

public void setBusy(boolean busy) {
this.busy = busy;
}
}
}

这个示例代码展示了如何在Java中手动实现一个MySQL数据库连接池。以下是如何使用该连接池的示例:

CustomConnectionPool cOnnPool= new CustomConnectionPool(
"com.mysql.cj.jdbc.Driver",
"jdbc:mysql://localhost:3306/mydatabase",
"username",
"password"
);
connPool.createPool();
Connection cOnn= connPool.getConnection();
// 使用连接进行数据库操作...
connPool.returnConnection(conn);

请注意,此示例是基于MySQL数据库编写的,使用时请根据实际数据库类型进行相应的调整。


推荐阅读
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • Java 类成员初始化顺序与数组创建
    本文探讨了Java中类成员的初始化顺序、静态引入、可变参数以及finalize方法的应用。通过具体的代码示例,详细解释了这些概念及其在实际编程中的使用。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
author-avatar
曾经的我们太矫情_377
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有