1、什么是数据库连接池

    我们现在在开发中一定都会用到数据库,为了提高我们的系统的访问速度,数据库优化是一个有效的途径。我们现在开发中使用数据库一般都要经历以下的四个步骤:(1)加载数据库的驱动类,(2)建立数据库连接,(3)进行数据操作,(4)关闭数据库连接;在这四步中建立数据库连接是一个比较耗时的操作,如果每次有新的操作数据库的需求都去重新建立数据库连接必然要耗费一部分时间,拖慢系统的访问速度;在这种情况下我们就需要数据库连接池,预先创建好一定数量的数据库连接,等我们现需要使用时直接从其中拿已经创建好了尚未使用的的数据库连接,这样就可以节省掉一部分时间,加快系统的访问速度,保存这些预先创建的一定数量的数据库连接的容器称之为数据库连接池。

2、现有的常用数据库连接池

    (1)DBCP数据库连接池

    (2)C3P0数据库连接池

3、数据库连接池原理

    数据库连接池通过预先创建一定数量的空闲的数据库连接,在需要数据库连接时直接从其中获取,而不要去重新创建而节省一定的时间。

    数据库连接池的连接有连个属性,一个是本数据库的真正的连接对象,一个是标志本连接是否是空闲的标志;当数据库连接池被初始化的时候,会去创建一定数       量(一般在配置文件中配置)的数据库连接,并且这些连接都是处于空闲状态的,当需要数据库连接时,直接从数据库连接池中获取已经创建并且空闲的数据库连               接  并将其致为非空闲状态,如果数据库连接池中没有了空闲的连接,则去看数据库连接池连接数量是否以达到最大值(一般在配置文件中配置),如果没有达到最            大 值则再去创建一定数量的空闲连接;当连接使用完毕后,并不真正的关闭连接,而是将连接的状态重新致为空闲。从而达到连接重复使用的效果,节省时间。

4、简易数据库连接池的实现

  (1)、创建数据库连接池的对象,对象包括真正的数据库连接池对象和是否可用的标志。

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; /**
* 数据库连接池对象
*/
public class SimplePoolEntity { //真正的数据库连接对象
private Connection connection;
//是否可用的标志,默认为true 可用
private boolean isUsable = true; public Connection getConnection() {
return connection;
} public void setConnection(Connection connection) {
this.connection = connection;
} public boolean isUsable() {
return isUsable;
} public void setUsable(boolean usable) {
isUsable = usable;
} /**
* 数据库操作方法
* @param sql 需要执行的sql语句
* @return ResultSet
*/
public ResultSet execSql(String sql){
ResultSet rs = null;
try {
Statement statement = connection.createStatement();
rs =statement.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
}

  (2)数据库连接池操作接口

/**
* 数据库连接池操作接口
*/
public interface SimplePoolService {
/**
* 连接池创建连接接口
* @param connCount 需要创建的连接数量
*/
void createConnection(int connCount) throws Exception; /**
* 获取数据库连接
* @return
* @throws Exception
*/
SimplePoolEntity getConnection();
}

  (3)数据库连接池操作实现

  数据库连接池配置文件:

  

#数据库的驱动类
simple.jdbc.driver = com.mysql.jdbc.Driver
#数据库的连接url
simple.jdbc.url = jdbc:mysql://localhost:3306/test
#数据库的连接用户名
simple.jdbc.username = root
#数据库的连接密码
simpel.jdbc.password = root
#数据库连接池的初始化连接数量
simple.init.count = 10
#数据库连接池的步进数量
simple.step.count = 4
#连接池的最大数量
simple.max.count = 100

  数据库连接池的实现

/**
* 数据库操作实现
* 本操作中将要实现数据库连接池的初始化工作,初始化参数采用配置文件的形式来进行配置
*
*/
public class SimplePoolServiceImpl implements SimplePoolService { private String jdbcDriver; // 数据库驱动
private String jdbcUrl; //数据库url
private String username; //用户名
private String password; //密码
private Integer initCount; //初始化数量
private Integer stepCount; //步进数量
private Integer maxCount; //最大数量 private SimplePoolEntity simplePoolEntity;
private Set<SimplePoolEntity> simplePoolEntitySet = new HashSet<>();
/**
* 构造方法初始化 数据库连接池
*/
public SimplePoolServiceImpl(){
init();
} /**
* 数据库连接池初始化
*/
private void init(){
//1.读取配置文件
InputStream in =this.getClass().getClassLoader().getResourceAsStream("simpleboolconfig.properties");
Properties properties = new Properties();
try {
properties.load(in);
//设置初始化参数
jdbcDriver = properties.getProperty("simple.jdbc.driver");
jdbcUrl = properties.getProperty("simple.jdbc.url");
username = properties.getProperty("simple.jdbc.username");
password = properties.getProperty("simpel.jdbc.password");
initCount = Integer.parseInt(properties.getProperty("simple.init.count"));
stepCount =Integer.parseInt( properties.getProperty("simple.step.count"));
maxCount =Integer.parseInt( properties.getProperty("simple.max.count"));
//加载数据库驱动
Driver driver = (Driver) Class.forName(jdbcDriver).newInstance();
//获取数据库管理对象
DriverManager.deregisterDriver(driver);
//初始化一定数量的连接
createConnection(initCount);
} catch (Exception e) {
e.printStackTrace();
} }
@Override
public void createConnection(int connCount) throws Exception {
//判断数据库连接池是否以达到最大连接数
if(simplePoolEntitySet.size() + connCount > maxCount){
throw new RuntimeException("连接池数量已到上限");
}
for (int i=0;i < connCount;i++){
simplePoolEntity = new SimplePoolEntity();
simplePoolEntity.setConnection(DriverManager.getConnection(jdbcUrl,username,password));
simplePoolEntity.setUsable(true);
simplePoolEntitySet.add(simplePoolEntity);
}
} @Override
public SimplePoolEntity getConnection() {
try {
SimplePoolEntity simplePoolEntity = getRealConection();
//为空时创建新的连接
while (simplePoolEntity == null){
createConnection(stepCount);
//创建连接比较耗时,建议在此处让线程延迟一定时间
Thread.sleep(3000);
simplePoolEntity = getRealConection();
}
} catch (Exception e) {
e.printStackTrace();
}
return simplePoolEntity;
} private SimplePoolEntity getRealConection() throws Exception{
//循环连接池,获取连接
for(SimplePoolEntity simplePoolEntity : simplePoolEntitySet){
//判断是否为空闲
if(simplePoolEntity.isUsable()){
//判断连接是否有效
if(!simplePoolEntity.getConnection().isValid(3000)){
//无效连接,重新创建连接替换该连接
Connection realConnect = DriverManager.getConnection(jdbcUrl,username,password);
simplePoolEntity.setConnection(realConnect);
}
//设置状态为不可用
simplePoolEntity.setUsable(false);
return simplePoolEntity;
}
}
return null;
}
}

  (4) 对外提供单例模式的数据库连接池管理对象

public class SimplePoolManger {
//私有化构造,禁止创建
private SimplePoolManger(){} //在静态内部类中实例化对象,达到懒汉单例模式
private static class ClassLoad{
public static SimplePoolService getSimplePoolService(){
return new SimplePoolServiceImpl();
}
}
public static SimplePoolService getInstace(){
return ClassLoad.getSimplePoolService();
}
}

  

Java数据库连接池原理与简易实现的更多相关文章

  1. JAVA和C#中数据库连接池原理与应用

    JAVA和C#中数据库连接池原理 在现在的互联网发展中,高并发成为了主流,而最关键的部分就是对数据库操作和访问,在现在的互联网发展中,ORM框架曾出不穷, 比如:.Net-Core的EFCore.Sq ...

  2. Java数据库连接池

    转载过来的,最近在做一个小网站,准备使用这种方法.     Java jdbc数据库连接池总结! 1. 引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及, ...

  3. 一个JAVA数据库连接池实现源码

    原文链接:http://www.open-open.com/lib/view/open1410875608164.html // // 一个效果非常不错的JAVA数据库连接池. // from:htt ...

  4. JDBC数据库连接池原理

    JDBC是java数据库连接的简称.它是一种用于实行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成.其相关的API都在java.sql.*包下 ...

  5. Java数据库连接池封装与用法

    Java数据库连接池封装与用法 修改于抄袭版本,那货写的有点BUG,两个类,一个用法 ConnectionPool类: package com.vl.sql; import java.sql.Conn ...

  6. Java数据库连接池的几种配置方法(以MySQL数据库为例)

    Java数据库连接池的几种配置方法(以MySQL数据库为例) 一.Tomcat配置数据源: 前提:需要将连接MySQL数据库驱动jar包放进Tomcat安装目录中common文件夹下的lib目录中 1 ...

  7. Java数据库连接池详解

    http://www.javaweb1024.com/java/JavaWebzhongji/2015/06/01/736.html 对于共享资源,有一个很著名的设计模式:资源池(Resource P ...

  8. 主流Java数据库连接池分析(C3P0,DBCP,TomcatPool,BoneCP,Druid)

    主流数据库连接池 常用的主流开源数据库连接池有C3P0.DBCP.Tomcat Jdbc Pool.BoneCP.Druid等 C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDB ...

  9. [转帖]为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用

    为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用 原创Clement-Xu 发布于2015-07-17 15:53:14 阅读数 57066  收藏 展开 HiKariCP是 ...

随机推荐

  1. 【TypeScript】TypeScript 学习 5——方法

    在 JavaScript 中,有两种方式定义方法. 1.命名的方法 function add(x,y){ return x+y; } 2.匿名方法 var myAdd = function(x,y) ...

  2. TCP/IP协议族分层

    协议族的分层抽象,一定意义上来说,每层敬职敬责的做自己的工作,同时也共同完成通讯协议的共同目标. 这是一个垂直划分的抽象层次,挺有意义. 1.链路层/数据链路层/网络接口层 操作系统中的设备驱动程序和 ...

  3. SqlServer Session共享注意点

    公司下派任务,之前的网站是一台服务器,由于用户过多,负载过大,现在老大要求多加一台服务器.加就加贝,应该跟我这DEV没有 关系吧,应该不会碰到Source的吧.但是,之前网站有一些数据是放在Sessi ...

  4. Qt使用gtest进行C++单元测试-01

    环境: win7/win10+qt5.8.0(MinGW), 1.gtest获取: 从:https://www.bogotobogo.com/cplusplus/google_unit_test_gt ...

  5. 《Python黑帽子:黑客与渗透测试编程之道》 Web攻击

    Web的套接字函数库:urllib2 一开始以urllib2.py命名脚本,在Sublime Text中运行会出错,纠错后发现是重名了,改过来就好: #!/usr/bin/python #coding ...

  6. iOS 卡顿

    1 使用 dispatch_async,也可能会出现卡顿. 由于mac系统允许overcommit,而iOS系统不允许overcommit 故要控制GCD队列的数量并且最好设置target queue ...

  7. Python(IO model)

    day34 IO model 举例:https://blog.csdn.net/ZWE7616175/article/details/80591587 参考:http://www.cnblogs.co ...

  8. HDU 1710Binary Tree Traversals(已知前序中序,求后序的二叉树遍历)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1710 解题思路:可以由先序和中序的性质得到 : 先序的第一个借点肯定是当前子树的根结点, 那么在 中序 ...

  9. Elasticsearch分页

    Elasticsearch的数据都存在每个节点的分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回.ElasticSearch的搜索请求一次请求最大量为10000.如果超过则会发生错误.那么, ...

  10. Linux命令学习与使用2

    1.Ctrl+a:跳到命令行首 Ctrl+E: 跳到命令行尾 Ctrl+L:清屏2.切换用户 su - 用户名3.更换yum镜像源 1.进入/etc/yum.repos.d 备份CentOS-Base ...