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. [mysql] mysql如何实现更新一条记录中某个字段值的一部分呢?

    场景:在平常我们使用word文档等等office办公软件时,我们常会使用搜索->替换的功能. mysql: 在mysql 中有时候,我们也需要这样子的实现: 实现 SQL 语句: update ...

  2. [php] try - catch exceptiong handler

    //http://stackoverflow.com/questions/1241728/can-i-try-catch-a-warningOne possibility is to set your ...

  3. 【Win10】实现控件倒影效果

    先引入个小广告: 最近买了台小米盒子折腾下,发觉 UI 还是挺漂亮的,特别是主页那个倒影效果. (图随便找的,就是上面图片底部的那个倒影效果.) 好了,广告结束,回归正题,这个倒影效果我个人觉得是挺不 ...

  4. java 执行sql文件

    # 背景 用例执行完毕,期望回滚数据,因此希望执行sql来回滚数据 # 步骤 直接show代码,借助的是mybatis的ScriptRunner /** * 执行xx库下的表备份脚本 * * @par ...

  5. SQL学习笔记1

    2018.10.15:周一   -- 返回前5个数据 SELECT TOP 5 * FROM Student;   -- 返回前50%的数据 SELECT TOP 50 PERCENT * FROM ...

  6. golang 编译为dll 的方法

    之前一直再找如何将geojson 转为 svg 格式的数据,看到github上大多都是js来转的,只有一篇是golang来做的,想来把它封成dll 给c#.c++ 调用,网上查了很多方法,并没有写的很 ...

  7. C#多线程编程系列(二)- 线程基础

    目录 C#多线程编程系列(二)- 线程基础 1.1 简介 1.2 创建线程 1.3 暂停线程 1.4 线程等待 1.5 终止线程 1.6 检测线程状态 1.7 线程优先级 1.8 前台线程和后台线程 ...

  8. UWP开发---通过委托跨页面导航

    -前言 做过.Net开发的都了解,当二级窗口操作主窗口的控件时通常用委托的方式.那么在UWP开发中,常常会遇到MainPage的二级Frame里面的内容去操作MainPage的导航跳转,具体看下图: ...

  9. 【cocos2d-x 手游研发小技巧(1)自定义制作怪物伤害数值】

    直插主题了,今天写了一下午,早就想要写这类似东西的,首先我不会选用CCLabelAtlas了,我直接用帧图片做. 首先我们要准备素材,我先把素材帖出来给大家: 这个是一张比较全的素材图,它包含了扣血的 ...

  10. 【Selenium专题】元素定位之一简单定位

    UI自动化工具千变万化.架构千变万化,但都逃离不开的关键一步就是元素定位.下面以Selenium为例介绍常见的几个元素定位方法 ID -元素id属性 WebElement El = driver.fi ...