实现一个简单的数据库连接池

前言:

  最近在搞一个项目,就是要把SqlServer数据全部导入到Oracle中,也要让项目由原来的SqlServer支持Oracle,于是自已在网上找了很多工具,发现导的时候都有问题,而且数据量非常庞大。一开始是自已手动导,将SqlServer数据库导成支持Oracle的sql文件,然后再把这个sql文件导入到Oracle中,发现将一个10万条的sql文件导入到Oracle中都要半小时,简直崩溃了!  想想单个导sql文件的方式属于单线程模式,因为使用PLSQL工具导是只有一个连接,于是就想到了使用多线程的方式导,也就是采用多个连接,多个子任务去导。因此便使用到了资源池的这种模式。使用多线程、资源池方式之后,速度提升了上千倍。

实现思路(如下图所示):

说明:

使用一个池也可实现资源池(即Map<Connetion, Params> pool 这种方式)但是这种逻辑复杂一点,即一个pool中要保证不连接数不能超过最大值又要判断哪些连接已经被占用。而我这里采用两个池来实现,一个是Used池,用来存放正在连接的资源;一个是Pool池,用来存放已经释放连接的资源;这样逻辑清晰简单。

实现步骤:

下面就是数据库连接池的简单实现方式:

1.编写一个对象池的抽象类

package com.core.jdbc;import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;public abstract class ObjectPool<T> {/*** 创建对象*/protected abstract T create();/*** 验证对象有效性*/public abstract boolean validate(T t, long createTime);/*** 使对象失效*/public abstract void expire(T t);private ConcurrentHashMap<T, Long> used; // 正在使用的,保存新建的资源private ConcurrentHashMap<T, Long> pool; // 未被使用的,保存释放的、未失效的资源,池子里面保存有效可用的对象private static int MAX_CONNECT_SIZE = 100;         // 最大连接数(这里也是pool的最大size,虽然没有定义pool的最大size,但是从整个逻辑上讲,pool的size是小于这个值的)public static int MAX_KEEP_ALIVE_TIME = 3000;      // 最大生存时间,这个时间也决定了创建连接的频率/*** 获得资源*/public synchronized T getResource() {T t = null;// 初始化if (null == pool) {pool = new ConcurrentHashMap<T, Long>();}if (null == used) {used = new ConcurrentHashMap<T, Long>();}// 超过最大连接数,等待(注意:这里可以加一个拒绝策略,即超时拒绝连接还是继续等待)while (used.size() >= MAX_CONNECT_SIZE) {try {this.wait(50);} catch (InterruptedException e) {e.printStackTrace();}} // 默认先从池子里面去取if (pool.size() > 0) {for (Entry<T, Long> entry : pool.entrySet()) {t = entry.getKey();if (null!=t) {break;}}pool.remove(t);} // 在池子中未取到,创建一个新的if (null == t) {t = create();}used.put(t, System.currentTimeMillis());this.notifyAll();return t;}/*** 释放某个资源*/public synchronized void release(T t) {if (null==t) {return;}while (used.size()==0) {try {this.wait(50);} catch (InterruptedException e) {e.printStackTrace();}}// 判断是否过有效期if (validate(t, used.get(t))) {// 放入池中
            pool.put(t, System.currentTimeMillis());used.remove(t);} else {expire(t);used.remove(t);}this.notifyAll();}}

2.编写数据库连接池的具体实现类

public class ConnectionPool extends ObjectPool<Connection> {private static int count = 0;public ConnectionPool() {try {Class.forName("oracle.jdbc.driver.OracleDriver");} catch (ClassNotFoundException e) {e.printStackTrace();}}@Overrideprotected Connection create() {Connection conn = null;try {conn = DriverManager.getConnection("jdbc:oracle:thin:@//127.0.0.1:1521/SZNY", "caoxiaobo", "123456");} catch (SQLException e) {e.printStackTrace();}count ++;logger.debug("建立连接次数" +count);return conn;}@Overridepublic boolean validate(Connection o, long createTime) {if (System.currentTimeMillis() - createTime > MAX_KEEP_ALIVE_TIME)return false;return true;}@Overridepublic void expire(Connection o) {try {o.close();} catch (SQLException e) {e.printStackTrace();}}
}

3.编写JDBC连接池单例类来确保只有一个池(确保ConnectionPool 对象唯一,即程序中所有的连接都从一个pool中去取)

public class JdbcConnection {private JdbcConnection () {}private static class Singleton {private static ConnectionPool pool = new ConnectionPool();}public static Connection getConnection() {return Singleton.pool.getResource();}public static void release(Connection conn) {Singleton.pool.release(conn);}}

4.并发测试类:

public class PoolTest {public static void main(String[] args) {Runnable run = new Runnable() {@Overridepublic void run() {Connection conn = JdbcConnection.getConnection();try {Thread.sleep(500);} catch (InterruptedException e) {// TODO Auto-generated catch block
                    e.printStackTrace();}JdbcConnection.release(conn);}};     // 创建2000个线程,模拟并发for (int i=0; i<2000; i++) {Thread thread = new Thread(run);thread.start();}}
}

测试结果:

假设并发请求有2000个(假设数据库最大连接数为150,这里设置要比它正常值小一点,即100),如果不使用资源池,那么就需要不断的创建、销毁2000次连接,对于服务器的性能来说影响还是比较大的。通过这个示例,我们可以看到这个结果(创建、销毁)远远小于2000次,大概测试了一下平均100-120之间。当然这里的这个值是根据它设定的生存时间来决定的。

转载于:https://www.cnblogs.com/caoxb/p/10032141.html

JDBC连接池的简单实现相关推荐

  1. jdbc封装mysql_用Java手动封装JDBC连接池(一)

    JDBC存在的问题 代码的冗余:在对数据库进行增删改查时,每个操作的JDBC流程和SQL执行代码的流程都一样,造成代码的冗余,所以我们可以把冗余的部分封装起来,封装之后,我们就不用再去写JDBC流程, ...

  2. 在独立Java应用程序中使用Tomcat JDBC连接池

    这是从我们的客人文章W4G伙伴克拉伦斯豪的作者临春3从A按. 您可能会在文章结尾找到本书的折扣券代码,仅适用于Java Code Geeks的读者! 请享用! 在需要数据访问权限的独立Java应用程序 ...

  3. 数据层优化-jdbc连接池简述、druid简介

    终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和dao层的优化 ...

  4. jdbc连接池工作原理_JDBC连接实际上如何工作?

    jdbc连接池工作原理 The JDBC Connection interface is a part of java.sql package. The java.sql.Connection int ...

  5. JDBC、封装JDBC连接池、第三方连接池工具

    主要内容: JDBC简介 JDBC来源 通过代码实现JDBC JDBC的改进需求 JDBC改进的代码实现 JDBC使用的设计模式 封装连接池 封装JDBC连接池 ThreadLoacl的使用 Thre ...

  6. HikariCP:一个叫光的JDBC连接池

    简介 天不生我李淳罡,剑道万古如长夜. Hikari [hi·ka·'lē] 是日语"光"的意思.HikariCP的卖点是快.简洁.可靠,整体非常轻量,只有130Kb左右. Hik ...

  7. 使用DBCP配置JDBC连接池

    使用DBCP配置JDBC连接池 1.DBCP简介 DBCP(DataBase connection pool),数据库连接池.是 apache 上的一个 java 连接池项目,也是 tomcat 使用 ...

  8. JDBC 连接池参数

    JDBC连接池参数: jdbc.initialSize=0 //初始化连接 jdbc.maxActive=30 //连接池的最大数据库连接数,设为0表示无限制 jdbc.maxIdle=20 //没有 ...

  9. 数据库连接之jdbc连接池

    BC 1. 概念:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库 JDBC本质:官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口,s ...

最新文章

  1. 细心看完这篇文章,刷新对Javascript Prototype的理解
  2. h.264的NAL和VCL
  3. docker 集群中文件挂载的问题
  4. Runtime之IMP指针,isa指针
  5. 李倩星r语言实战_《基于R的统计分析与数据挖掘》教学大纲
  6. NB-IoT在智能锁领域的应用
  7. mysql 存储过程 简书_MySQL学习之存储过程
  8. npcap lookback adapter回环网卡是什么 它的作用是什么
  9. AttributeError: module ‘ahocorasick‘ has no attribute ‘Automaton‘
  10. 中国传统文化的现代意义
  11. catia怎么进入装配_catia装配详细教程
  12. 校园网不能建立到远程计算机,校园网已拒绝远程连接是什么问题及如何解决
  13. 使用Drupal Console,出现Failed to decode response: zlib_decode(): data error Retrying with degraded mode
  14. 【原创】(进阶)VMware16.1.2通过PE+Dism++绕过TPM限制安装Win11首个正式原版镜像
  15. 谈谈数据挖掘和机器学习
  16. MQTT-SN协议阅读之MQTT-SN vs MQTT
  17. Kali之——设置静态IP
  18. 南阳市区彩礼 wribao.php230.com,2021南阳彩礼钱一般给多少 河南南阳2021年结婚彩礼...
  19. python安装第三方包_python 安装第三方包
  20. 改进飞碟(Hit UFO)游戏

热门文章

  1. 我在亚信实习的日记(结束)
  2. @Scheduled 定时任务经验分享
  3. python jsonpath_Python_JsonPath
  4. 小米即将推出OLED电视,冲击行业老大创维
  5. 终端SSH连接linux
  6. QQ无法安装 系统时间问题
  7. jenkins查看端口号 修改默认端口号
  8. 我一个人的前端自学之路
  9. 《团队作业》五小福团队作业--UNO-- LandingDay--降落
  10. 【蓝桥杯】【回形取数】