JDBC数据库连接池

267 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

什么是数据库连接池?

数据库连接的建立及关闭是极耗资源的操作,在多层结构的应用环境中,这种资源的耗费对系统性能影响尤为明显。但是对于一个复杂的数据库应用,情况就完全不同了,每次获取连接,一个数据库连接对象均对应一个物理数据库连接,频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。

数据库连接池的解决方法是:当应用程序启动时,系统主动建立足够的数据库连接,并将这些连接组成一个连接池。每次应用程序请求数据库连接时,无须重新打开连接,而是从连接池中取出已有的连接进行使用,使用完不再关闭数据库连接,即使conn.close(),也是直接将连接归还给连接池。通过使用连接池,将大大提高程序的运行效率。

对于共享资源的情况,有一个通用的设计模式:资源池(Resource Pool),用于解决资源的频繁请求、释放所造成的性能下降。

JDBC的数据库连接池使用Javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由商用服务器等提供实现,也有一些开源组织提供实现(如DBCP和C3P0等)。

下面我们讲一下C3P0数据源具体实现

C3P0

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

首先在src目录下写一个C3P0的配置文件,命名为 c3p0-config.xml,一定要这样命名

c3p0-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/book?useUnicode=true&amp;characterEncoding=UTF8&amp;useSSL=true</property>
		<property name="user">root</property>
		<property name="password">123456</property>
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">10</property>
		<property name="minPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</default-config>
</c3p0-config>

这里我数据库的名字是 book

再新建一个数据库工具类C3P0Util.java

C3P0Util.java

package com.gpnu.book.common;

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

import com.mchange.v2.c3p0.ComboPooledDataSource;


public class C3P0Util {
	// 定义一个数据库对象
	private static ComboPooledDataSource ds = new ComboPooledDataSource("mysql");

	// 从连接池中取用一个连接
	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = ds.getConnection();
		} catch (Exception e) {
			System.out.println("数据库连接出错!" + e.getMessage());
		}
		return conn;
	}

	// 释放连接回连接池
	public static void closeResultSet(ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				System.out.println("数据库连接ResultSet关闭出错!" + e.getMessage());
			}
		}
	}
	
	
	public static void closePrepareStatement(PreparedStatement pst) {
		if (pst != null) {
			try {
				pst.close();
			} catch (SQLException e) {
				System.out.println("数据库连接PreparedStatement关闭出错!" + e.getMessage());
			}
		}
	}

	public static void closeConnection(Connection conn) {
			try {
				if (conn != null) {
					conn.close();					
				}
			} catch (SQLException e) {
				System.out.println("数据库连接Connection关闭出错!" + e.getMessage());
			}
	}
}

这样配置完毕,我们就可以来使用数据库连接池了,例如:

Connection conn = null;
PreparedStatement pstam = null;		
ResultSet rs = null;
	
conn = C3P0Util.getConnection();
pstam = conn.prepareStatement("select * from tbl_book");
rs = pstam.executeQuery();