主流的第三方数据库连接池

在实际应用中,通常不需要我们自己编写数据库连接池,目前市面上已经有很多组织提供了数据库连接池,常见的主要有下面几个:

C3p0

开源的,成熟的,高并发第三方数据库连接池,作者是 Steve Waldman,相关的文档资料比较完善,大名鼎鼎的hibernate框架就使用了c3p0数据库连接池。

项目地址:http://www.mchange.com/projects/c3p0/index.html

dbcp

全称是DataBase Connection Pool,它是由Apache开发的一个数据库连接池,在tomcat7版本之前都是使用dbcp作为数据库连接池,不过dbcp性能不太好,apache又开发了tomcat jdbc pool来替代dbcp。

项目地址:http://commons.apache.org/proper/commons-dbcp/

tomcat jdbc pool

由于dbcp的性能不太好,apache又新开发了一款数据库连接池-tomcat jdbc pool,有的地方也称之为JDBC Connection Pool。

项目地址:http://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html

Druid

作者是阿里巴巴的wenshao,号称是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。

项目地址:https://github.com/alibaba/druid

BoneCP

其官方说该数据库连接池性能非常棒,不过现在已经不更新了,转到了HiKariCP上。

项目地址:http://www.jolbox.com/

HiKariCP

Hikari是日语光的意思,作者可能想以此来表达HiKariCP速度之快。比之前的BoneCP性能更加强大,它官方展示了一些性能对比的数据,通过数据可以看出HiKariCP完虐c3p0,dbcp,tomcat jdbc pool等其他数据库连接池。并且它的库文件差不多就130kb,非常轻巧。

项目地址:https://github.com/brettwooldridge/HikariCP

Proxool

早期的一些项目中使用的多一些,现在该数据库连接池源码已经有一阵子不更新了。

项目地址:http://proxool.sourceforge.net/

以上是目前市面上一些主流的数据库连接池基本是就是这些了,太多了,咱们就选两个简单介绍下, 通常在实际应用中会将数据库连接池和spring等常用框架配置在一起使用,因为框架还目前咱们还没有讲,所以先看下在不使用框架的前提下,该如何使用数据库连接池 。

c3p0

第一步:

下载相关jar包:

百度网盘:https://pan.baidu.com/s/1nwhU553

下载后将项目两个jar包拷贝到项目中

c3p0-0.9.5.2.jar

mchange-commons-java-0.2.11.jar

在稍微旧点的版本中只需要拷贝一个c3p0的jar就行,后来c3p0将里面的一些模块分离出来,就有了mchange-commons-java的jar了。

另外不要忘记拷贝数据库的驱动jar包。

第二步:

在项目的src目录下创建c3p0-config.xml文件,当然你也可以创建一个c3p0.properties文件,这两个都支持。在xml文件编写下面内容:

com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/test-pool
root
monkey1024
10
30
100
10

第三步:

创建一个数据库test-pool,里面创建一个测试表t_user,建表语句如下:

CREATE TABLE `t_user` (
`id` varchar(10) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

第四步:

创建一个C3P0Util的工具类,内容如下:

package com.monkey1024.jdbc.util;
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0Util {
// 得到一个c3p0的数据源
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 从数据源中得到一个连接对象
// 这个返回的connection实际上是c3p0经过装饰之后的connection
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException("服务器错误");
}
}
//查看连接池的状态
public static void poolStatus() {
try {
System.out.println("清闲的:" + dataSource.getNumIdleConnections());
System.out.println("忙碌的:" + dataSource.getNumBusyConnections());
System.out.println("所有的:" + dataSource.getNumConnections());
} catch (SQLException e) {
e.printStackTrace();
}
}
}

创建一个测试类C3P0Test:

package com.monkey1024.jdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import com.monkey1024.jdbc.util.C3P0Util;
public class C3P0Test {
public static void main(String[] args) {
insert();
try {
//睡眠一下方便查看状态
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
C3P0Util.poolStatus();
}
public static void insert() {
String sql = "insert into t_user(id,name) values('1030','jack')";
try (Connection conn = C3P0Util.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
//查看连接池的状态
C3P0Util.poolStatus();
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
}
}
druid

这里介绍一下咱们国人写的druid,在性能方面表现不错。

第一步:

下载相关jar包:druid-1.1.8.jar

百度网盘:https://pan.baidu.com/s/1pMGwxZX

第二步:

创建dbconfig.properties配置文件,在文件中编写下面内容,druid可以根据url自动识别driverclass,所以在配置文件中可以省略:

url=jdbc:mysql://localhost:3306/test-pool
username=root
password=monkey1024
#初始化的连接个数
initialSize=10
#最大连接个数
maxActive=20
#最小连接个数
minIdle=10

第三步:

创建数据库,内容同上面的c3p0的第三步一样

第四步:

编写DruidUtil工具类:

package com.monkey1024.jdbc.util;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
public class DruidUtil {
// 得到一个Druid的数据源
private static DruidDataSource dataSource = null;
static{
Properties properties = new Properties();
try {
//加载配置文件
//properties.load(new FileInputStream("build/classes/dbconfig.properties"));
//下面这种写法会从classpath下来查找配置文件
properties.load(DruidUtil.class.getClassLoader().getResourceAsStream("dbconfig.properties"));
//得到一个数据源
dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
// 从数据源中得到一个连接对象
// 这个返回的connection实际上是Druid经过装饰之后的connection
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException("服务器错误");
}
}
}

编写测试类DruidTest:

package com.monkey1024.jdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import com.monkey1024.jdbc.util.DruidUtil;
public class DruidTest {
public static void main(String[] args) {
insert();
try {
//睡眠一下方便查看状态
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void insert() {
String sql = "insert into t_user(id,name) values('12012','jack')";
try (Connection conn = DruidUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
}
}