今天来说一下数据库链接池技术.其实这个名词也就是听起来高大上一点,实际上并非很复杂的内容,相信在个人讲解下,而且本身实际的将代码写一遍以后,可以对这项技术有较为深入的理解.废话很少说,开始讲解.java
所谓的数据库链接池技术,就是用来分配,管理,释放数据库链接的.你也许会问,好像我直接用JDBC也可以实现这些功能吧. 嗯,你说的没错,JDBC确实也能够,可是,你记不记得,咱们使用JDBC技术的时候,每次用完了,是否是都会将链接关闭;等到下一次再用的时候,是否是都得将数据库链接再打开? 实际上,数据库连接资源是十分宝贵的,咱们在小型的项目中还看不出来,在高并发的项目中,你会发现,这样频繁的打开和关闭数据库连接是对服务器的一种摧残,十分影响效率. 那么,数据库链接池是如何作的呢? 实现思路是这样的:在每次有访问的时候,数据库链接池会给用户分配一个数据库链接,当用户用完了链接以后,链接池再将链接回收,放回一个链接集合中. 原理就是这样的,咱们来看一下这张图加深印象 mysql
注意:下面的代码我是分块讲解的,你一个个粘贴下来,最后确定也是能运行的,为了方便,我会在讲完以后,给出完整的实现代码.sql
private final int init_count = 3; //初始化连接数目
private final int max_count = 6; //最大链接数
private int current_count = 0; //到当前链接数
复制代码
private LinkedList<Connection> pool = new LinkedList<Connection>();
复制代码
//构造函数,初始化连接放入链接池
public MyPool() {
for (int i=0;i<init_count;i++){
//记录当前链接数
current_count++;
//createConnection是自定义的建立连接函数.
Connection connection = createConnection();
pool.addLast(connection);
}
}
复制代码
public Connection createConnection() {
Class.forName("com.mysql.jdbc.Driver");
Connection connection =DriverManager.getConnection("jdbc:mysql://localhost:3306/keyan","root","root");
return connection;
}
复制代码
public Connection getConnection() {
if (pool.size() > 0){
//removeFirst删除第一个而且返回
//如今你必定看懂了我说的为什要用LinkedList了吧,由于下面的这个
//removeFirst()方法会将集合中的第一个元素删除,可是还会返回第一个元素
//这样就省去了咱们不少没必要要的麻烦
return pool.removeFirst();
}
if (current_count < max_count){
//记录当前使用的链接数
current_count++;
//建立连接
return createConnection();
}
throw new RuntimeException("当前连接已经达到最大链接数");
}
复制代码
public void releaseConnection(Connection connection){
if (pool.size() < init_count){
pool.addLast(connection);
current_count--;
}else {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
复制代码
整个的实现过程就是这样的,下面我把所有的代码贴出来,方便你们学习.数据库
//单元测试
@Test
public class MyPool {
private final int init_count = 3; //初始化连接数目
private final int max_count = 6; //最大
private int current_count = 0; //到当前链接数
//链接池,用来存放初始化连接
private LinkedList<Connection> pool = new LinkedList<Connection>();
//构造函数,初始化连接放入链接池
public MyPool() {
for (int i=0;i<init_count;i++){
//记录当前链接数
current_count++;
Connection connection = createConnection();
pool.addLast(connection);
}
}
//建立新的链接
public Connection createConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/keyan","root","root");
return connection;
}catch (Exception e){
System.out.println("数据库连接异常");
throw new RuntimeException();
}
}
//获取连接
public Connection getConnection() {
if (pool.size() > 0){
//removeFirst删除第一个而且返回
return pool.removeFirst();
}
if (current_count < max_count){
//记录当前使用的链接数
current_count++;
//建立连接
return createConnection();
}
throw new RuntimeException("当前连接已经达到最大链接数");
}
//释放连接
public void releaseConnection(Connection connection){
if (pool.size() < init_count){
pool.addLast(connection);
current_count--;
}else {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
复制代码
本身跑了一遍代码以后,你是否是发现原来看起来很复杂的技术,并不像咱们想得那样? 好了,介绍完了基本的数据库链接池技术原理以后,咱们就要介绍两个开源的优秀的数据链接池技术. 其实,真正的数据库链接池要考虑的东西比咱们刚才写的这玩意复杂,现阶段不须要咱们写这样复杂的东西,不过若是你感兴趣的话,能够看看数据库链接池的源代码--没错,这两个链接池都是开源的.OK,接下来就开始吧!tomcat
首先,sun公司规定,链接池技术需实现javax.sql.DataSource接口,也就是说,若是你要本身实现数据库链接池,那么就必须实现这个接口.是否是很牛比的样子,实际上,做为标准制定方,sun公司仍是有不少要求的,这是做为标准制定者的权利,因此,企业或者国家每每会对一些关键技术标准的制定打得头破血流.额,扯远了...bash
其实,你可能不知道,若是你的tomcat通过特殊的配置,也是能够做为数据库链接池使用的,由于tomcat内置的就是DBPC.. 想要使用DBPC,你必须导入三个jar文件:commons-dbcp2-2.2.0.jar,commons-pool2-2.5.0.jar,commons-logging-1.2.jar.我想,以你的聪明才智,想要获取这三个jar文件,必定是小菜一叠,这是一个软件开发者的必备技能--学会如何搜索. 使用起来就很是简单了.使用的方式主要有两种,一种是硬编码的方式,就是本身手动设置各类参数,另一种就是配置相应的配置文件,而后载入就好了.服务器
BasicDataSource dataSource = new BasicDataSource();
//参数配置:初始化链接数,最大链接数,链接字符串,驱动,用户,密码
dataSource.setInitialSize(3); //最大初始化连接
dataSource.setMaxTotal(6); //最大连接
dataSource.setMaxIdle(3000); //最大空闲时间
dataSource.setUrl("jdbc:mysql:///keyan"); //url
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword("root");
//获取连接
Connection connection = dataSource.getConnection();
connection.prepareStatement("SELECT * FROM e_person").execute();
connection.close();
复制代码
使用查询的时候,只须要按照原来JDBC的操做方式就好了,这个没啥好说的,按照我上面的配置方式实现就好了,必定不要忘记导入包.微信
//建立properties配置文件
Properties properties = new Properties();
//获取文件流
InputStream in = DBCPTest.class.getResourceAsStream("db.properties");
//加载配置文件
properties.load(in);
//建立数据源对象
BasicDataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
//获取连接
Connection connection = dataSource.getConnection();
ResultSet resultSet = connection.prepareStatement("SELECT * FROM e_person").executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("work_name"));
}
connection.close();
复制代码
上面是基本的操做流程,下面咱们看一下这个xml文件的配置 文件db.properties
并发
url=jdbc:mysql:///keyan
driverClassName=com.mysql.jdbc.Driver
username=root
password=root
initialSize=3
maxActive=6
maxIdle=3000
复制代码
特别要注意的一点是,这个配置文件必定要放在和你的这DBPC类放在同一个包下. 都完成了以后,直接用就能够了.函数
c3p0一样是很是优秀的链接池技术,这个须要导入的文件比较少,只有一个c3p0-0.9.1.2.jar.本身去网站上找一下就行了. 使用c3p0一样是有两种方式,分别也是硬编码方式和配置文件方式.
//配置相关的参数
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setJdbcUrl("jdbc:mysql:///keyan");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setInitialPoolSize(3);
dataSource.setMaxPoolSize(6);
dataSource.setMaxIdleTime(1000);
Connection connection = dataSource.getConnection();
//sql语句
ResultSet resultSet = connection.prepareStatement("SELECT * FROM e_project").executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("project_name"));
}
connection.close();
复制代码
和上面同样,简单的使用一下就好了,知道如何使用就行.至于更加深层次的东西,有兴趣的话慢慢研究吧.
ComboPooledDataSource dataSource = new ComboPooledDataSource();
Connection connection = dataSource.getConnection();
ResultSet resultSet = connection.prepareStatement("SELECT * FROM e_project").executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("project_name"));
}
connection.close();
复制代码
乍一看,你可能会问,不是配置文件方式实现吗?没错,只是这个是隐式的调用,不须要你实现,只须要新建一个ComboPooledDataSource对象就好了,默认调用xml文件,文件路径是src根目录.也就是说,你只须要将配置文件写在src目录下就好了.重点是如何写这个xml文件. 注意,文件名c3p0-config.xml,这个文件名不能改,必须是这个,文件路径必须是src根目录,不然读取不到.
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">3</property>
<property name="maxPoolSize">6</property>
<property name="maxIdleTime">1000</property>
</default-config>
</c3p0-config>
复制代码
配置文件的参数大致上用到的就这么多,固然,你也能够去找一下相关的资料,了解一下更加详细的参数意义,这些参数,我么平常使用足够了.
因为数据库链接得以重用,避免了频繁建立,释放链接引发的大量性能开销。在减小系统消耗的基础上,另外一方面也增长了系统运行环境的平稳性。
数据库链接池在初始化过程当中,每每已经建立了若干数据库链接置于链接池中备用。此时链接的初始化工做均已完成。对于业务请求处理而言,直接利用现有可用链接,避免了数据库链接初始化和释放过程的时间开销,从而减小了系统的响应时间
对于多应用共享同一数据库的系统而言,可在应用层经过数据库链接池的配置,实现某一应用最大可用数据库链接数的限制,避免某一应用独占全部的数据库资源
在较为完善的数据库链接池实现中,可根据预先的占用超时设定,强制回收被占用链接,从而避免了常规数据库链接操做中可能出现的资源泄露
感谢您的阅读,欢迎指正博客中存在的问题,也能够跟我联系,一块儿进步,一块儿交流!
微信公众号:进击的程序狗 邮箱:roobtyan@outlook.com 我的博客:roobtyan.cn 扫描下面的二维码关注我吧,你将收获到意想不到的东西哟…… 给你们准备了一份很是棒的JAVA的视频教程,从JAVA基础一直到JAVAWEB,还有很是强大的项目实战。 就在个人微信公众号里,回复java就可查看,免费的呦!