Java数据库连接池原理与简易实现
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数据库连接池原理与简易实现的更多相关文章
- JAVA和C#中数据库连接池原理与应用
JAVA和C#中数据库连接池原理 在现在的互联网发展中,高并发成为了主流,而最关键的部分就是对数据库操作和访问,在现在的互联网发展中,ORM框架曾出不穷, 比如:.Net-Core的EFCore.Sq ...
- Java数据库连接池
转载过来的,最近在做一个小网站,准备使用这种方法. Java jdbc数据库连接池总结! 1. 引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及, ...
- 一个JAVA数据库连接池实现源码
原文链接:http://www.open-open.com/lib/view/open1410875608164.html // // 一个效果非常不错的JAVA数据库连接池. // from:htt ...
- JDBC数据库连接池原理
JDBC是java数据库连接的简称.它是一种用于实行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成.其相关的API都在java.sql.*包下 ...
- Java数据库连接池封装与用法
Java数据库连接池封装与用法 修改于抄袭版本,那货写的有点BUG,两个类,一个用法 ConnectionPool类: package com.vl.sql; import java.sql.Conn ...
- Java数据库连接池的几种配置方法(以MySQL数据库为例)
Java数据库连接池的几种配置方法(以MySQL数据库为例) 一.Tomcat配置数据源: 前提:需要将连接MySQL数据库驱动jar包放进Tomcat安装目录中common文件夹下的lib目录中 1 ...
- Java数据库连接池详解
http://www.javaweb1024.com/java/JavaWebzhongji/2015/06/01/736.html 对于共享资源,有一个很著名的设计模式:资源池(Resource P ...
- 主流Java数据库连接池分析(C3P0,DBCP,TomcatPool,BoneCP,Druid)
主流数据库连接池 常用的主流开源数据库连接池有C3P0.DBCP.Tomcat Jdbc Pool.BoneCP.Druid等 C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDB ...
- [转帖]为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用
为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用 原创Clement-Xu 发布于2015-07-17 15:53:14 阅读数 57066 收藏 展开 HiKariCP是 ...
随机推荐
- python 删除一个目录下的所有文件
一个目录下有文件,文件夹,文件夹里又有文件.文件夹....用python脚本,实现,递归删除一个目录下的所有文件: 目录结构如下: 其中我们要删除所有文件 代码实现如下: import os CUR_ ...
- 设计模式之组合模式(Composite Pattern)
一.什么是组合模式? 组合模式提供了一种层级结构,并允许我们忽略对象与对象集合之间的差别 调用者并不知道手里的东西是一个对象还是一组对象,不过没关系,在组合模式中,调用者本来就不需要知道这些 二.举个 ...
- 获取微信签名,并保存在xml文件中
using System; using System.Linq; using System.Text; using System.Web; using System.Web.UI; using Sys ...
- 记录.NET Core部署到Linux之.NET Core环境搭建(1)
1.在安装.NET之前,您需要注册Microsoft密钥.注册产品存储库和安装所需的依赖项. 启动我们的虚拟机,输入以下命令: sudo rpm -Uvh https://packages.micro ...
- BitAdminCore框架更新日志20180518
20180518更新内容 1.重构调整QQ登录代码,使用JObject,减少代码,增加access_token自动续期(未测试). 2.重构调整微信登录代码,使用JObject,减少代码,增加acce ...
- Java 类型转换工具类(持续更新)
简介 将项目中用到的类型转换做个记录. 详细代码 @Component public class TypeUtil { // [start]字符串转各种格式 // 字符串转日期(格式:"yy ...
- SQL 2012新分页方式
--2012的OFFSET分页方式 (推荐使用 - 较为方便) select number from spt_values where type='p' order by number offset ...
- SSRS (一)创建基础报表
ReportService创建基础报表 1.数据库SQL Server2012选择SQL Server Data Tools 2.创建商业智能(BI)项目 选择报表服务器项目 ReportServic ...
- Sentinel 哨兵 实现redis高可用
本文链接:http://www.cnblogs.com/zhenghongxin/p/8885879.html 我们知道redis是有主从复制的,例如下图: 但如果master主进程挂掉之后,没有sl ...
- jenkins 配置。
为了避免在jenkins操作过程中的权限问题. 将安装在/Users/Shared/jenkins目录下的卸载. sudo launchctl unload /Library/LaunchDaemon ...