对Java初学者来说,数据库连接池同其它的XX池一样,看起来是很神秘的一种技术,其实都是难者不会,会者不难的情况。当了解了数据库连接池技术之后,数据库连接池并不神秘而是一个非常简单的小技巧。
为什么会有数据库连接池呢?对于一个系统来说,如果没有数据库连接,当你每次需要进行数据库操作时,都要获取连接,完成操作之后将连接关闭。当系统访问量上来之后,你就会发现系统将会有大量的实践都花在获取数据库连接和关闭连接上。因此如果我们建立一个数据库连接池,在系统启动时,一次性的获取若干条数据库连接加入到连接池中,当我们需要进行数据库操作时,直接从数据库连接池中拿到连接,用完之后不再关闭,而是将其放入连接池中,这样系统运行时将再不会有频繁的获取连接和关闭连接了。下面,我们就自己写一个简单的数据库连接池,并加以测试。
1. ConnectionPool类:数据库连接池类. 运用单例模式,当要进行数据库操作时,先调用ConnectionPool.getInstance()方法,获取数据库连接池的实例,然后调用connectionPool.getConnection()方法获取数据库连接,使用完连接之后调用connectionPool.release(Connection conn)来代替connection.close()方法来将获得的连接释放到连接池中,以便重复利用。这样就解决了频繁打开和关闭数据库连接池的问题。
ConnectionPool.java
public class ConnectionPool {
private List<Connection> connections ;
private int poolSize = 1;//
private String url;
private String username;
private String password;
private String driverClassName;
private static ConnectionPool instance = null;
private ConnectionPool() {
initialize();
}
/**
* 初始化方法
*/
private void initialize() {
connections = new ArrayList<Connection>(poolSize);
readConfig();
addConnection();
}
/**
* 读取数据库连接池的配置文件
*/
private void readConfig() {
String path = System.getProperty("user.dir")+"/resources/config/jdbc.properties";
try {
FileInputStream is = new FileInputStream(path);
Properties prop = new Properties();
prop.load(is);
driverClassName = prop.getProperty("jdbc.driverClassName");
url = prop.getProperty("jdbc.url");
username = prop.getProperty("jdbc.username");
password = prop.getProperty("jdbc.password");
poolSize = Integer.parseInt(prop.getProperty("jdbc.poolSize"));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 往数据库连接池中添加连接
*/
private void addConnection() {
for (int i=0; i < poolSize; i++) {
try {
Class.forName(driverClassName);
Connection connection = java.sql.DriverManager.getConnection(url, username, password);
connections.add(connection);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 获取数据库连接池
* @return
*/
public static ConnectionPool getConnectionPoolInstance() {
if (instance == null) instance = new ConnectionPool();
return instance;
}
/**
* 从数据库连接池中获取数据库连接
* @return
*/
public synchronized Connection getConnection() {
if (connections.size() <= 0) return null;
Connection connection = connections.get(0);
connections.remove(0);
return connection;
}
/**
* 释放数据库连接
* 使用完数据库连接池之后调用这个方法来代替close方法
* @param connection
*/
public synchronized void realase(Connection connection) {
connections.add(connection);
}
/**
* 关闭数据库连接池
*/
public synchronized void closePool() {
for (int i =0; i < connections.size(); i++) {
Connection connection = connections.get(i);
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
connections.remove(i);
}
}
}
2. jdbc.propeties 数据库连接池配置文件,初始化数据库连接池时使用到。
jdbc.driverClassName=oracle.jdbc.xa.client.OracleXADataSource
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:mgodb
jdbc.username=CAR
jdbc.password=CAR
jdbc.poolSize=10
3. ConnectionPoolTest类: 测试类, 通过与不使用数据库连接池进行数据库访问所消耗的时间进行对比,为了使测试尽可能准确,通过100次循环调用,对比时间总和。
ConnectionPoolTest.java
public class ConnectionPoolTest extends TestCase {
public void testConnectionPoolTest() throws Exception {
String sql = "SELECT * FROM T_CR_CAR_TYPE_BRAND";
ConnectionPool connectionPool = null;
long starttime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
connectionPool = ConnectionPool.getConnectionPoolInstance();
Connection conn = connectionPool.getConnection();
ResultSet rs;
Statement stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()) {
}
rs.close();
stmt.close();
rs = null;
stmt = null;
connectionPool.realase(conn);
}
connectionPool.closePool();
System.out.println("经过100次循环调用,使用连接池花费的时间:"
+ (System.currentTimeMillis() - starttime) + "ms\n");
String driverClassName = "oracle.jdbc.xa.client.OracleXADataSource";
String url = "jdbc:oracle:thin:@127.0.0.1:1521:mgodb";
String username = "CAR";
String password = "CAR";
starttime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
Class.forName(driverClassName);
Connection conn = DriverManager.getConnection(url, username,
password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
}
rs.close();
stmt.close();
conn.close();
rs = null;
stmt = null;
conn = null;
}
System.out.println("经过100次循环调用,不使用连接池花费的时间:" + (System.currentTimeMillis() - starttime) + "ms\n");
}
}
通过测试结果可以发现,使用数据库连接池所消耗的实践要小于不使用数据库连接池的,当调用的次数增加时,差异将会更加明显。
当然这个数据库连接池仅仅是用来了解数据库连接池的原理而已,对于超时的连接并没有强制收回的机制,也没有限制用户调用close方法来关闭连接。仅供学习。。。。
分享到:
相关推荐
使用数据库连接池方式能对数据库的连接进行管理和维护,上层应用程序通过数据库连接池使用数据库资源能提升系统性能,充分利用系统资源。文章通过介绍、分析数据库连接池工作的基本原理,了解目前流行的WEB服务器在...
基于Java的数据库连接池的研究与实现,谢俊,陈明,介绍了基于Java的数据库的访问机制,对实际应用中出现的问题进行了分析,提出了数据库连接池技术的解决方案,分析了连接池的工作原理,�
基于嵌入式SQL的数据库连接池应用技术研究.pdf
基于JDBC的数据库连接池技术研究与应用,基于JDBC的数据库连接池技术研究与应用,数据库连接池
使用数据库连接池方式能对数据库的连接进行管理和维护,上层应用程序通过数据库连接池使用数据库资源能提升系统性能,充分利用系统资源。文章通过介绍、分析数据库连接池工作的基本原理,了解目前流行的WEB服务器在...
数据库连接池技术研究与应用.pdf
Java数据库连接)是一种用于执行SQL语句的JavaAPI,可以为多种关系型数据库(如Oracle、Sybase、SQL Server、Access等)提供统一访问接口,它由一组Java语言编写的类和接口组成,使数据库开发人员能够用标准JavaAPI编写...
简而言之,数据库连接池主要作用是负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不再是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而...
学案之数据库连接池技术研究与应用.pdf
网络QoS机制不足以提供完全的端到端的性能保证, 在由三层结构构成的电子商务网站中, 基于反馈控制理论, 提出并实现了在应用服务器的数据库连接池中的绝对延迟保证, 对数据库连接池作出了改进, 确保带有高优先级请求...
数据库连接池在电子病历共享系统中的应用研究,刘言,杜军平,本文构建了数据库连接池系统,可完成对多个不同数据库的连接的管理,从而满足应用系统对多个数据库的访问需求,并可方便地增减被
数据库连接池在油料补给优化系统中的应用,杨振东,郑冀,介绍了基于Java的数据库连接池的工作原理及模型,并以油料补给优化系统为例,展示了数据库连接池能很好地应用在对数据库访问频繁��
首先讲述了JAVA的数据库访问机制,并对实际应用中出现的问题进行了分析,然后提出了能改善WEB应用系统性能的连接池技术的一般工作机制,并用JAVABEAN构造了一个基本的连接池。最后结合当前热门的JSP技术列举了应用...
提出一种自优化数据库连接池的设计方式。它可根据应用规模动态地调整设置参数,进而选取对应的管理策略,其中策略可以存储在连接池的配置文件中或作为知识库保存。在对连接资源进行有效管理的同时,可以对连接池的...
基于JDBC的数据库连接池在大学评教移动系统中的应用,刘伟,刘伟,在基于JDBC 的数据库应用开发中,数据库连接的管理是一个难点,因为它是决定应用性能的一个重要因素。本文依据基于JDBC 的数据库连��