(一)介绍
1:维基百科
在软件工程中,数据库连接的连接池是一个缓存维护,这样未来请求时可以重用数据库的连接是必需的。连接池是用来提高性能的数据库上执行命令。为每个用户开放和维护一个数据库连接,尤其是动态数据库驱动的网站应用程序的请求,是昂贵和浪费资源。在连接池中,创建一个连接后,它被放置在连接池里,再次使用,因此不需要建立一个新的连接。如果正在使用的所有连接,一个新的连接和添加到池。连接池还减少了用户必须等待的时间建立一个连接到数据库。
2:主要因素
1:最小连接数:最小连接数对于数据连接池进行制约,即不管数据连接是否有人使用,连接池一直至少存在着这么多的连接数量。
2:最大连接数:即连接池中能够申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将会被加入到等待队列中。
3:主要的连接池技术
1:C3P0连接池:开源免费的连接池,主要通过ComboPooledDataSource进行数据设置和获取连接。可以通过配置xml配置文件,属性文件,或者直接在程序中设置数据源来建立连接池和获取连接。
2:DBCP连接池:(DataBase connection pool)是Apache上的一个连接池项目。它通过连接池预先同数据库建立一些连接放在内存中,应用程序需要建立数据库连接时直接从连接池中申请一个连接使用,用完后由连接池回收该连接,从而达到连接复用,减少资源消耗的目的。
(二)自定义简单连接池
大致思路:
1:设置初始连接数
2:设置最大连接数
3:设置当前连接数
4:如果用户连接数据库则拿出一个连接对象,如果用户使用完毕则放回到连接池中。注意,如果连接池中没有连接对象,那么新建一个连接对象,只要不超过最大连接数即可。用户释放连接的话,如果连接池的数量不超过初始容量(注意不是最大容量)的话,即放回到集合容器中,如果超过了初始容量,则直接释放掉,对象置空。
package demo1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
/**
* 自定义连接池
**/
public class ObjectPool {
private int initSize = 2; //初始连接数
private int maxSize = 5; //最大连接数
private int currentSIze = 0; //当前连接数
private LinkedList<Connection> list = null; //容器
public ObjectPool() {
init();
}
//设置最小连接数
public void setInitSize(int initSize) {
this.initSize = initSize;
}
//设置最大连接数
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
//初始化驱动
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//初始化
public void init() {
list = new LinkedList<>();
for (int i = 0; i < initSize; i++) {
list.add(createConnection());
currentSIze++;
}
}
//创建连接
public Connection createConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(
"jdbc:mysql:///test", "root", "root");
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
//用户从连接池中取出连接对象
public Connection getPoolConn() {
//1:连接池是否还有连接对象
if (list.size() > 0) {
Connection connection = list.removeFirst();
return connection;
}
//2:如果连接池没有可用连接,则新建连接,但是当前连接数不能超过最大连接数
if (currentSIze < maxSize) {
currentSIze++;
return createConnection();
}
throw new RuntimeException("没有可用的连接....");
}
//释放连接
public void releaseConn(Connection conn) {
if (conn != null) {
//1.连接个数比初始个数大,直接释放
if (currentSIze > initSize) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
currentSIze--;
return;
}
//2.连接个数小于初始个数,放入连接池
list.add(conn);
}
}
}
(三)C3P0连接池
1:第一种在程序中直接设置声明和获取连接
public static void main(String[] args) {
ComboPooledDataSource p = new ComboPooledDataSource();
try {
p.setDriverClass("com.mysql.jdbc.Driver"); //驱动
p.setJdbcUrl("jdbc:mysql:///test"); //连接信息
p.setUser("root"); //用户
p.setPassword("root"); //密码
p.setInitialPoolSize(20); //初始连接数
p.setMaxPoolSize(100); //最大连接数
p.setMaxIdleTime(60); //最大空闲时间,单位毫秒
Connection connection = p.getConnection(); //获取对象
System.out.println(connection);
} catch (PropertyVetoException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
2:使用xml配置文件c3p0-config.xml
(将该文件放入classpath中即可,然后直接就可以在程序中获取连接)
<c3p0-config>
<default-config>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">25</property>
<property name="minPoolSize">5</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///test</property>
<property name="user">root</property>
<property name="password">9527</property>
</default-config>
</c3p0-config>
@Test
public void myTest() {
ComboPooledDataSource p1 = new ComboPooledDataSource();
Connection connection = null;
try {
connection = p1.getConnection();
System.out.println(connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
3:使用属性文件的方式
(也是放在classpath目录下,调用同上)
#
# This file is detritus from various testing attempts
# the values below may change, and often do not represent
# reasonable values for the parameters.
#
#c3p0.testConnectionOnCheckout=true
#c3p0.testConnectionOnCheckin=true
#c3p0.minPoolSize=3
#c3p0.maxPoolSize=20
#c3p0.checkoutTimeout=2000
#c3p0.idleConnectionTestPeriod=5
#c3p0.maxConnectionAge=10
#c3p0.maxIdleTime=2
#c3p0.maxIdleTimeExcessConnections=1
#c3p0.propertyCycle=1
#c3p0.numHelperThreads=10
#c3p0.unreturnedConnectionTimeout=15
#c3p0.debugUnreturnedConnectionStackTraces=true
#c3p0.maxStatements=30
#c3p0.maxStatementsPerConnection=5
#c3p0.maxAdministrativeTaskTime=3
#c3p0.preferredTestQuery=SELECT 1
#c3p0.preferredTestQuery=SELECT a FROM emptyyukyuk WHERE a = 5
#c3p0.preferredTestQuery=SELECT a FROM testpbds WHERE a = 5
#c3p0.usesTraditionalReflectiveProxies=true
#c3p0.automaticTestTable=PoopyTestTable
#c3p0.acquireIncrement=4
#c3p0.acquireRetryDelay=1000
#c3p0.acquireRetryAttempts=60
#c3p0.connectionTesterClassName=com.mchange.v2.c3p0.test.AlwaysFailConnectionTester
#c3p0.initialPoolSize=10
c3p0.jdbcUrl=jdbc:mysql:///test
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.user=root
c3p0.password=root
#c3p0.user=poop
#c3p0.password=scoop
#com.mchange.v2.log.MLog=com.mchange.v2.log.log4j.Log4jMLog
#com.mchange.v2.log.MLog=com.mchange.v2.log.jdk14logging.Jdk14MLog
#com.mchange.v2.log.MLog=com.mchange.v2.log.FallbackMLog
#com.mchange.v2.log.NameTransformer=com.mchange.v2.log.PackageNames
#com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL=ALL
#com.mchange.v2.c3p0.VMID=poop