ToB企服应用市场:ToB评测及商务社交产业平台
标题:
JDBC p5 数据库连接池
[打印本页]
作者:
tsx81428
时间:
2023-7-31 19:01
标题:
JDBC p5 数据库连接池
数据库连接池
传统获取Connection问题分析
传统的JDBC数据库使用 DriverManager 来获取,
每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证IP地址,用户名和密码(0.05 ~ 1 s 时间)
。需要数据库连接的时候,就向数据库要求一个,频繁的进行数据库连接操作将占用很多的系统资源,容易造成服务器崩溃。
每一次数据库连接使用后都得断开,如果程序出现异常而未能关闭,将导致数据库
内存泄漏
,最终将导致重启数据库。
传统获取连接的方式,不能控制创建的连接数量,如果连接过多,也可能导致内存泄露,MySQL崩溃。
解决传统开发中的数据库连接问题,可以采用数据库连接池技术。
案例:
package com.hspedu.jdbc.datasource;
import com.hspedu.jdbc.utils.JDBCUtils;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
public class ConQuestion {
//代码 连接mysql 5000次
@Test
public void testCon(){
long start = System.currentTimeMillis();
for (int i = 0; i < 5000; i++){
//使用传统jdbc连接方式
Connection connection = JDBCUtils.getConnection();
//可能会抛出too many connections的异常
//再看看,如果得到连接就立即关闭,总共会耗时多久
JDBCUtils.close(null, null, connection);
}
long end = System.currentTimeMillis();
System.out.println("耗时 = " + (end - start));//耗时 = 6598
}
}
复制代码
数据库连接池原理
基本介绍
预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需要从“缓冲池”中取出一个,使用完毕之后再放回去(放回连接,其实就是指程序不再引用这个连接)。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序
重复使用
一个现有的数据库连接,而不是重新建立一个。
当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
原理示意图:
常用的数据库连接池
JDBC 的数据库连接池使用 javax.sql.DateSource 来表示,DataSource 只是一个接口,该接口通常由第三方提供实现。
数据库连接池种类:**
C3P0 数据库连接池:速度相对较慢,稳定性不错 (hibernate,spring);
DBCP 数据库连接池:速度相对C3P0较快,但不稳定;
Proxool 数据库连接池:有监控连接池状态的功能,稳定性较C3P0差一点;
BoneCP 数据库连接池:速度快;
Druid(德鲁伊) 数据库连接池:是阿里提供的数据库连接池,集DBCP、C3P0、Proxool优点于一身的数据库连接池;
C3P0的使用
需要自行导入相关的jar包。
方式1:相关参数,在程序中指定user,url, password。
方式2: 使用配置文件的模板来完成。
代码演示:
package com.hspedu.jdbc.datasource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.jupiter.api.Test;
import java.beans.PropertyVetoException;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class C3P0_ {
//方式1:相关参数,在程序中指定user, url, password
@Test
public void testC3P0_01() throws IOException, PropertyVetoException, SQLException {
//1. 创建一个数据源对象
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//2. 通过配置文件获取相关连接信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
//给数据源(数据源负责连接,连接池) comboPooledDataSource 设置参数
comboPooledDataSource.setDriverClass(driver);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
//设置初始化连接数
comboPooledDataSource.setInitialPoolSize(10);
//最大连接数
comboPooledDataSource.setMaxPoolSize(50);
//获取连接
//测试连接池的效率,连接5000次
long start = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
Connection connection = comboPooledDataSource.getConnection();//这个方法就是从DateSource接口实现的
// System.out.println("连接OK");
//关闭
connection.close();
}
long end = System.currentTimeMillis();
System.out.println("c3p0 5000次连接mysql 耗时 = " + (end - start));//c3p0 5000次连接mysql 耗时 = 280,之前传统的耗时 = 6598
}
//第二种方式, 使用配置文件的模板来完成
//1. 将c3p0 提供的 c3p0.config.xml 拷贝到src目录
//2. 该文件指定了连接数据库和连接池的相关参数
@Test
public void testC3P0_02() throws SQLException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("hsp_edu");//填入数据源名称
long start = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
Connection connection = comboPooledDataSource.getConnection();//这个方法就是从DateSource接口实现的
// System.out.println("连接OK");
//关闭
connection.close();
}
long end = System.currentTimeMillis();
System.out.println("c3p0 第二种方式500000次连接mysql 耗时 = " + (end - start));//c3p0 第二种方式500000次连接mysql 耗时 = 1452
}
}
复制代码
配置文件 c3p0-config.xml:
<c3p0-config>
<named-config name="hsp_edu">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_learning</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxStatementPerConnection">2</property>
</named-config>
</c3p0-config>
复制代码
Druid(德鲁伊)的使用
需要自行导入相关的jar包。
代码演示:
package com.hspedu.jdbc.datasource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.jupiter.api.Test;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
public class Druid_ {
@Test
public void testDruid() throws Exception {
//1. 加入 Druid jar包
//2. 加入 配置文件 druid.properties,将该文件拷贝到项目的src目录
//3. 创建 Properties 对象
Properties properties = new Properties();
properties.load(new FileInputStream("src\\druid.properties"));
//4. 创建一个指定参数的数据库连接池
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
long start = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
Connection connection = dataSource.getConnection();
// System.out.println("连接成功");
connection.close();
}
long end = System.currentTimeMillis();
System.out.println("druid连接池, 连接500000次 耗时 = " + (end - start));//druid连接池, 连接500000次 耗时 = 549
}
}
复制代码
配置文件 druid.properties:
#key=value
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc_learning?rewriteBatchedStatements=true
username=root
password=root
#initial connection size
initialSize=10
#min idle connection size
minIdle=5
#max active connection size
maxActive=50
#max wait time (5000 mil seconds)
maxWait=5000
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4