文章目录
- 简述数据库连接池的作用
- 几种的数据库连接池
- DBCP数据库连接池获取数据库连接
- C3P0数据库连接池获取数据库连接
- Druid数据库连接池获取数据库连接
简述数据库连接池的作用
对于一个简单的数据库引用,如果是应用程序直接获取数据库连接的话,如果用于对数据库的访问不是很频繁,这种情况可以简单的在需要访问数据库时,创建一个链接,用完关闭它,这样做不会有太明显的性能上的开销。但是对于复杂的数据库引用,情况就截然不同了,频繁的建立、关闭连接,会极大的减低系统的性能。通过连接池,可以有效解决这个问题。连接池的作用是为了提高性能,避免重复多次的打开数据库连接而造成性能的下降和系统资源的浪费;连接池是将已经创建好的连接保存在池中,当有请求来时,直接使用已经创建好的连接对数据库进行访问。这样省略了创建和销毁的过程。这样以提高系统的性能。
几种的数据库连接池
1、DBCP
由Apache开发的一个Java数据库连接池项目, Jakarta commons-pool对象池机制,Tomcat使用的连接池组件就是DBCP。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar,预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统。
2、C3P0
开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。单线程,性能较差,适用于小型系统,代码600KB左右。
3、Druid
Druid:Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;Druid是一个开源项目,源码托管在github上。
DBCP数据库连接池获取数据库连接
导入DBCP的jar包的时候,需要注意的是:不可以只是导入dbcp的jar包commons-dbcp2-2.8.0.jar,还需要导入commons-logging-1.2.jar包和commons-pool2-2.9.0.jar,否则就会发生报错。
1、直接获取数据库连接,代码实现:
public class DBCPTest {
public static void main(String[] args) {
DBCPTest test = new DBCPTest();
test.getConnection();
}
public void getConnection() {
Connection connection = null;
try {
BasicDataSource bds = new BasicDataSource();//通过new来创建一个BasicDataSource对象
//设置连接的基本属性
bds.setUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=UTC");
bds.setDriverClassName("com.mysql.cj.jdbc.Driver");
bds.setUsername("root");//注意Username中的name没有大写
bds.setPassword("root");
//设置数据库连接池的基本属性
//调用getConnection方法,从而返回一个Connection对象
connection = bds.getConnection();
System.out.println(connection);
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(connection != null){
try {
connection.close();//释放资源
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
2、通过配置文件来获取数据库连接:
基本步骤:
1、首先定义一个配置文件,这里定义的是dbcp.properties,在配置文件中设置连接的基本信息,例如url/driverClassName/username/password等,同时还可以设置数据库连接池管理的基本信息等
2、在定义数据库连接池这个类中获取BasicDataSource对象时,需要通过BasicDataSourceFactory的静态方法createDataSource(),并且这个方法的参数时我们刚刚定义的配置文件的路径
3、获取BasicDataSource对象之后,调用getConnection方法,从而返回一个Connection对象
代码实现:
配置文件dbcp.properties:
url=jdbc:mysql://localhost:3306/db1?serverTimezone=UTC
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=root
测试类:
public class DBCPTest {
public static void main(String[] args) {
DBCPTest test = new DBCPTest();
//DBCP数据库连接池获取连接的方式一:直接获取
//输出1117509763, URL=jdbc:mysql://localhost:3306/db1?serverTimezone=UTC, MySQL Connector/J
// test.getConnection();
//方式二:通过配置文件进行获取
test.getConnection2();
}
public void getConnection2() {
Connection connection = null;
try {
Properties pro = new Properties();
//通过相应的方法,从而获得读取相应的配置文件的流
FileInputStream is = new FileInputStream(new File("D:/IDEA/JDBC/day01_JDBC/src/dbcp.properties"));
pro.load(is);//通过调用load方法,从而将读取流中的数据进行加载
//BasicDataSourceFactory类调用静态方法createDataSource方法,并且这个方法的参数是一个配置文件,从而返回一个BasicDataSource对象
BasicDataSource dataSource = BasicDataSourceFactory.createDataSource(pro);
//BasicDataSource对象调用getConnection方法,从而返回一个Connection对象
connection = dataSource.getConnection();
System.out.println(connection);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(connection != null){
try {
connection.close();//释放资源
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
C3P0数据库连接池获取数据库连接
导入C3P0的jar包的时候需要注意的是,**不只是导入c3p0-0.9.5.2.jar包,还要导入mchange-commons-java-0.2.12.jar包才可以,否则就会发生报错。
**
1、直接获取数据库连接,代码实现:
public class C3P0Test {
public static void main(String[] args) {
C3P0Test test = new C3P0Test();
//通过基本的方式,从而实现数据库来连接池来获取数据库
//test.getConn1();
//通过配置文件来实现数据库连接池获取数据库,值得注意的是这个配置文件的名字如果是通过xml为后缀,则名字必须是c3p0-config.xml
test.getConn2();
}
public void getConn1() {
/**
* 导入驱动C3P0数据库连接池jar包 --值得注意的是,如果单单添加
* c3p0-0.9.5.2.jar包,此时就会发生报错NoClassDefError,需要
* 在导入一个mchange-commons-java-0.2.12.jar包才可以
*/
//新建一个CombPooledDataSource对象
ComboPooledDataSource comb = new ComboPooledDataSource();
Connection connection = null;
//设置数据库的基本信息
try {
//设置数据库的基本信息
comb.setDriverClass("com.mysql.jdbc.Driver");
comb.setJdbcUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=UTC");
comb.setUser("root");
comb.setPassword("root");
//此时ComboPooledDataSource对象调用getConnection方法,即返回一个Connection对象
connection = comb.getConnection();
System.out.println(connection);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(connection != null){
//最后需要将连接的数据库关闭,但是建议不要关闭数据库连接池
try {
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
2、通过配置文件进行获取,值得注意的是,如果配置文件的后缀是xml的话,那么这个配置文件的名字只能是c3p0-config.xml,基本步骤:
1、定义一个配置文件c3p0-config.xml,并且在这个配置文件中设置连接的基本信息,url、driverClass、user、password,同时也可以设置数据库连接池管理的基本信息。但是想要新建xml文件的时候,却发现没有xml这个选项,这时候我们可以有以下步骤:
其中的代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
<default-config> <!-- 这一块是可以删除的default-config -->
<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
<user-overrides user="test-user">
<property name="maxPoolSize">10</property>
<property name="minPoolSize">1</property>
<property name="maxStatements">0</property>
</user-overrides>
</default-config>
<!-- This app is massive! -->
<named-config name="intergalactoApp">
<property name="acquireIncrement">50</property>
<property name="initialPoolSize">100</property>
<property name="minPoolSize">50</property>
<property name="maxPoolSize">1000</property>
<!-- intergalactoApp adopts a different approach to configuring statement caching -->
<property name="maxStatements">0</property>
<property name="maxStatementsPerConnection">5</property>
<!-- he's important, but there's only one of him -->
<!--user-overrides这一块也可以删除的 -->
<user-overrides user="master-of-the-universe">
<property name="acquireIncrement">1</property>
<property name="initialPoolSize">1</property>
<property name="minPoolSize">1</property>
<property name="maxPoolSize">5</property>
<property name="maxStatementsPerConnection">50</property>
</user-overrides>
</named-config>
</c3p0-config>
2、在测试类中定义ComboPooledDataSource对象时,构造方法的参数是 中的intergalactoApp,但是这个是自定义的,我们随便定义。
3、ComboPooledDataSource对象调用getConnection方法,从而返回一个Connection对象
代码实现:
配置文件c3p0-config.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
<named-config name="c3p0config">
<!--设置数据连接的基本信息 -->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db1?serverTimezone=UTC</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 设置数据连接池管理的基本信息 -->
<!--如果数据库连接池的连接数不够的时候,那么c3p0就会一次性向数据库服务器申请的连接数 -->
<property name="acquireIncrement">5</property>
<!--定义数据库连接池初始的时候连接数目-->
<property name="initialPoolSize">100</property>
<!--定义数据库连接池的中维护最少的连接 -->
<property name="minPoolSize">50</property>
<!--定义数据库连接池中维护最多的连接数 -->
<property name="maxPoolSize">100</property>
<!--定义数据库连接池中维护的最多的statement对象 -->
<property name="maxStatements">10</property>
<!-- 定义每一个连接中执行的statement对象最多有多少个 -->
<property name="maxStatementsPerConnection">2</property>
</named-config>
</c3p0-config>
测试类:
public class C3P0Test {
public static void main(String[] args) {
C3P0Test test = new C3P0Test();
//通过配置文件来实现数据库连接池获取数据库,值得注意的是这个配置文件的名字如果是通过xml为后缀,则名字必须是c3p0-config.xml
test.getConn();
}
public void getConn(){
//通过new来新建ComboPooledDataResources对象,同时构造参数是配置文件的名字
ComboPooledDataSource comb = new ComboPooledDataSource("c3p0config"); //这个c3p0config是在named-config后的name属性自定义的
Connection connection = null;
//调用getConnection方法,从而返回一个连接
try {
connection = comb.getConnection();
System.out.println(connection);
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
测试结果:
Druid数据库连接池获取数据库连接
导入jar包的时候,直接导入druid-1.0.9.jar即可。
1、直接获取数据库连接
代码实现:
public class DruidTest {
public static void main(String[] args) {
DruidTest test = new DruidTest();
test.getConnection();
}
public void getConnection(){
Connection connection = null;
try{
DruidDataSource druidDataSource = new DruidDataSource();
//设置数据库连接的基本信息
druidDataSource.setUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=UTC");
druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
druidDataSource.setUsername("root");
druidDataSource.setPassword("root");
//调用getConnection方法,从而返回一个Connection对象
connection = druidDataSource.getConnection();
System.out.println(connection);
}catch (Exception e){
e.printStackTrace();
}finally{
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
运算结果:
结果出现了testWhileIdle is true, validationQuery not set,目前还没有办法找到解决办法,查找的大部分都是说到配置文件的,但是这里并没有使用配置文件,如果大家有解决办法的,请指教哈。
2、通过配置文件来获取
基本思路和DBCP的基本思路是一样的:
1、定义一个配置文件druid.properties,并在这个配置文件中设置数据库连接的基本信息,url,driverClassName,username,password,同时可以设置数据库连接池的相关信息。
配置文件druid.properties:
url=jdbc:mysql://localhost:3306/db1?serverTimezone=UTC
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=root
但是这样就真的可以保证不会向上面一样,出现testWhileIdle is true, validationQuery not set 和{dataSource-1} inited的警告吗,答案是否,因为这样子的话,和直接获取是没什么两样的,只是将基本信息放在了配置文件而已,所以还要再配置文件中添加如下代码才可以:?
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
所以配置文件中是这样的:
url=jdbc:mysql://localhost:3306/db1?serverTimezone=UTC
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=lf_MySQL
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
2、在测试类中获取DruidDataSource对象的时候,需要通过DruidDataSourceFactory的静态方法createDataSource方法,从而返回一个DataSource对象,此时需要注意类型转换,否则就会发生报错。
//通过new来定义一个DruidDataSource对象
DruidDataSource dds = (DruidDataSource) DruidDataSourceFactory.createDataSource(pro);//注意类型强转
3、获取DruidDataSource之后,调用getConnection方法,返回一个Connectio对象
代码实现:
public class DruidTest {
public static void main(String[] args) {
DruidTest test = new DruidTest();
test.getConnection();//通过配置文件获取
}
/**
* 通过配置文件来获得数据库连接
* 基本步骤:
* 1、DruidDataSourceFactory对象调用creatDataSource方法,从而返回一个DataSource对象,如果是
* DruidDataSource对象的话,那么需要类型强转,值得注意的是,方法的参数是一个properties对象
* 2、调用getConnection方法,从而返回一个Connection对象
*/
public void getConnection() {
Connection connection = null;
try {
Properties pro = new Properties();
FileInputStream fis = new FileInputStream(new File("D:/IDEA/JDBC/day01_JDBC/src/druid.properties"));
pro.load(fis);
//通过new来定义一个DruidDataSource对象:
DruidDataSource dds = (DruidDataSource) DruidDataSourceFactory.createDataSource(pro);
//设置数据库连接池的管理属性
//调用getConnection方法,从而返回一个Connection对象
connection = dds.getConnection();
System.out.println(connection);
}catch (Exception e) {
e.printStackTrace();
} finally{
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
运算结果为: