在企业级开发中,我们往往不会直接使用原生的JDBC操作来实现与数据库得连接。因为数据库的连接是一个很宝贵的资源且耗时,我们往往会在内存中引入一个资源池来统一管理数据库的连接。这个模式也被总结为一种设计模式:资源池模式和单例模式。

关于原理部分就不多做介绍了,这里也是做一个简单的原理实现。

ObjectPool连接池接口

package com.test.pool;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap; public abstract class ObjectPool<T> {
private long expirationTime; private Hashtable<T, Long> locked, unlocked; public ObjectPool() {
expirationTime = 30000; // 30 seconds
locked = new Hashtable<T, Long>();
unlocked = new Hashtable<T, Long>();
} protected abstract T create(); public abstract boolean validate(T o); public abstract void expire(T o); public synchronized T checkOut() {
long now = System.currentTimeMillis();
T t;
if (unlocked.size() > 0) {
Enumeration<T> e = unlocked.keys();
while (e.hasMoreElements()) {
t = e.nextElement();
if ((now - unlocked.get(t)) > expirationTime) {
// object has expired
unlocked.remove(t);
expire(t);
t = null;
} else {
if (validate(t)) {
unlocked.remove(t);
locked.put(t, now);
return (t);
} else {
// object failed validation
unlocked.remove(t);
expire(t);
t = null;
}
}
}
}
// no objects available, create a new one
t = create();
locked.put(t, now);
return (t);
} public synchronized void checkIn(T t) {
locked.remove(t);
unlocked.put(t, System.currentTimeMillis());
}
}

JDBCConnectionPool 连接池实现

package com.test.pool;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class JDBCConnectionPool extends ObjectPool<Connection> { private String driver, url, username, password; private JDBCConnectionPool() { } private static volatile JDBCConnectionPool instance; public static JDBCConnectionPool getInstance() {
if(instance == null) {
synchronized (JDBCConnectionPool.class) {
if(instance == null) {
instance = new JDBCConnectionPool();
}
}
}
return instance;
} @Override
protected Connection create() {
try {
return (DriverManager.getConnection(url, username, password));
} catch (SQLException e) {
e.printStackTrace();
return (null);
}
} @Override
public void expire(Connection o) {
try {
((Connection) o).close();
} catch (SQLException e) {
e.printStackTrace();
}
} @Override
public boolean validate(Connection o) {
try {
return (!((Connection) o).isClosed());
} catch (SQLException e) {
e.printStackTrace();
return (false);
}
} public String getDsn() {
return url;
} public void setDsn(String dsn) {
this.url = dsn;
} public String getUsr() {
return username;
} public void setUsr(String usr) {
this.username = usr;
} public String getPwd() {
return password;
} public void setPwd(String pwd) {
this.password = pwd;
} public String getDriver() {
return driver;
} public void setDriver(String driver) {
this.driver = driver;
} public void loadDriver() {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
}
} }

Main测试

package com.test.pool;

import java.sql.Connection;
import java.sql.SQLException; public class Main {
public static void main(String args[]) throws SQLException { JDBCConnectionPool pool = JDBCConnectionPool.getInstance();
pool.setDriver("com.mysql.jdbc.Driver");
pool.setDsn("jdbc:mysql://192.168.2.113:3306/jhbims?useSSL=false&useUnicode=true&characterEncoding=UTF-8&amp;autoReconnect=true");
pool.setUsr("jhbims");
pool.setPwd("jhbims");
pool.loadDriver(); // Get a connection:
Connection con = pool.checkOut();
System.out.println(con.isValid(0)); pool.checkIn(con); }
}

本文由博客一文多发平台 OpenWrite 发布!

资源池模式和单例模式实现的自定义数据库连接池java实现版的更多相关文章

  1. 【Java EE 学习 15】【自定义数据库连接池之动态代理的使用】

    一.动态代理的作用 使用动态代理可以拦截一个对象某个方法的执行,并执行自定义的方法,其本质是反射 优点:灵活 缺点:由于其本质是反射,所以执行速度相对要慢一些 二.数据库连接池设计思想 1.为什么要使 ...

  2. 经典的单例模式c3p0来控制数据库连接池

    package com.c3p0.datapools; //数据库连接池  单例模式 import java.sql.Connection; import java.sql.SQLException; ...

  3. 【MySQL】自定义数据库连接池和开源数据库连接池的使用

    数据库连接池的概念 数据库连接背景 数据库连接是一种关键的.有限的.昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性 ...

  4. [数据库连接池] Java数据库连接池--DBCP浅析.

    前言对于数据库连接池, 想必大家都已经不再陌生, 这里仅仅设计Java中的两个常用数据库连接池: DBCP和C3P0(后续会更新). 一. 为何要使用数据库连接池假设网站一天有很大的访问量,数据库服务 ...

  5. 一个经试用效果非常不错的数据库连接池--JAVA

    前言: 虽说现在许多企业级的应用服务器均自己带有数据库连接池功能,就连 Tomcat 也支持了这种功能.然而在许多时候,我们还是要使用数据库连接池,如:访问数据库的 Java 桌面应用程序等.这个数据 ...

  6. 自定义连接池java.lang.ClassCastException: com.sun.proxy.$Proxy4 cannot be cast to java.sql.Connection

    原因:Connection.getInterfaces() 与数据库驱动有关,数据库驱动不同 Connection.getInterfaces() 的结果也就不同,Connection.getInte ...

  7. JDBC 学习笔记(三)—— 数据源(数据库连接池):DBCP数据源、C3P0 数据源以及自定义数据源技术

    本文目录:        1.应用程序直接获取连接的缺点(图解)        2.使用数据库连接池优化程序性能(图解)        3.可扩展增强某个类方法的功能的三种方式        4.自定 ...

  8. Java Web(九) JDBC及数据库连接池及DBCP,c3p0,dbutils的使用

    DBCP.C3P0.DBUtils的jar包和配置文件(百度云盘):点我下载 JDBC JDBC(Java 数据库连接,Java Database Connectify)是标准的Java访问数据库的A ...

  9. 开源数据库连接池之DBCP

    本篇介绍几种开源数据库连接池,同时重点讲述如何使用Apache公司的的DBCP数据库连接池. 前面一篇博客已经重点讲述了使用数据库连接池的好处,即是将多次创建连接转变为一次创建而使用长连接模式.这样能 ...

随机推荐

  1. java编程思想第四版第十章习题

    第一题 package net.mindview.innerclasses; public class Outer { class Inner { Inner(){ System.out.printl ...

  2. 【计算机网络】TCP基础知识详解

    1. TCP概念相关 [!NOTE] TCP(Transmission Control Protocol),又叫传输控制协议. TCP协议是面向连接的,可靠的,基于字节流的传输协议.在基于 TCP 进 ...

  3. scrapy介绍及使用

    scrapy的流程 其流程可以描述如下: 调度器把requests-->引擎-->下载中间件--->下载器 下载器发送请求,获取响应---->下载中间件---->引擎-- ...

  4. docker容器访问宿主机的IP——以rocketmq管理工具为例

    在宿主机(MacOS系统)上运行了原生的RocketMQ服务,为了方便管理,需要以Docker方式运行RocketMQ的管理工具——rocketmq-console (项目地址:https://git ...

  5. 2019牛客暑期多校训练营(第九场) E-All men are brothers(并查集+组合数学)

    >传送门< 题意:最初有 n个人且互不认识,接下来 m行,每行有 x,y表示x和y交朋友,朋友关系满足自反性和传递性,每次输出当前选取4个人且互不认识的方案数. 思路:比赛的时候知道是用并 ...

  6. 2019牛客暑期多校训练营(第九场) E All men are brothers

    传送门 知识点:并查集+组合数学 并查集合并操作可以理解为使得两个集合的人互相成为朋友,也就是两个集合并在了一起,答案是要求从所有人中挑出四个互相不是朋友的四个人,比较基础的组合数学知识,但因为每个集 ...

  7. Java方法的可变参数

    class Demo { public static int sum(int ... data) { //此处可以传递一个数组,也可以是多个参数 int sum = 0; for (int i : d ...

  8. day20191006假期作业收尾

    国庆作业:(轻重缓急,重点代码看懂理解了.每天重心就是代码,理解代码,理解,understand the code.花时间花功夫.只要功夫深,铁杵磨成针.) 一.使用DAO设计模式操作数据库CRUD( ...

  9. split分割(拆分)文件

    split分割(拆分)文件 需求:指定文件大小拆分文件 # ll -h test/ |grep vmcore -rw-r--r-- 1 root root  12G 12月  7 00:20 vmco ...

  10. Day01-变量/常量/数据类型/流程控制之 if

    1.变量 把程序运行的中间结果临时的存在内存里,以便后续的代码调用.代指一些复杂的.过长的数据. 声明变量  name = 'Dylan' # 把数据'Dylan'声明(赋值)给变量 nmae,以便后 ...