1、简介

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。

2、为什么要用连接池

如果按照单个连接来进行数据库操作,在高并发的情况下会导致数据库连接数耗尽的问题,而且单个连接的频繁创建和关闭,极大地增加了数据库的开销。针对这些,数据库连接池技术就能很好的解决这些问题。

3、实现

定义连接对象

import java.sql.Connection;

/**
*
*/
public class PoolConnection { private Connection connect;
//false 繁忙,true 空闲
private boolean status; public PoolConnection() {
} public PoolConnection(Connection connect, boolean status) {
this.connect = connect;
this.status = status;
} public Connection getConnect() {
return connect;
} public void setConnect(Connection connect) {
this.connect = connect;
} public boolean isStatus() {
return status;
} public void setStatus(boolean status) {
this.status = status;
} //释放连接池中的连接对象
public void releaseConnect(){
this.status = true;
}
}

定义一个接口获取连接对象

public interface DataSource {
PoolConnection getDataSource();
}

实现类

public class DataSourceImpl implements DataSource {

    private ReentrantLock lock = new ReentrantLock();
//定义连接池中连接对象的存储容器
private List<PoolConnection> list = Collections.synchronizedList(new LinkedList<>());
//定义数据库连接属性
private final static String DRIVER_CLASS = PropertiesUtils.getInstance().getProperty("jdbc.driver_class");
private final static String URL = PropertiesUtils.getInstance().getProperty("jdbc.url");
private final static String USERNAME = PropertiesUtils.getInstance().getProperty("jdbc.username");
private final static String PASSWORD = PropertiesUtils.getInstance().getProperty("jdbc.password"); //定义默认连接池属性配置
private int initSize = 2;
private int maxSize = 4;
private int stepSize = 1;
private int timeout = 2000; public DataSourceImpl() {
initPool();
} //初始化连接池
private void initPool() {
String init = PropertiesUtils.getInstance().getProperty("initSize");
String step = PropertiesUtils.getInstance().getProperty("stepSize");
String max = PropertiesUtils.getInstance().getProperty("maxSize");
String time = PropertiesUtils.getInstance().getProperty("timeout"); initSize = init == null ? initSize : Integer.parseInt(init);
maxSize = max == null ? maxSize : Integer.parseInt(max);
stepSize = step == null ? stepSize : Integer.parseInt(step);
timeout = time == null ? timeout : Integer.parseInt(time); try {
//加载驱动
Driver driver = (Driver) Class.forName(DRIVER_CLASS).newInstance();
//使用DriverManager注册驱动
DriverManager.registerDriver(driver);
} catch (Exception e) {
e.printStackTrace();
}
} @Override
public PoolConnection getDataSource() {
PoolConnection poolConnection = null;
try {
lock.lock();
//连接池对象为空时,初始化连接对象
if (list.size() == 0) {
createConnection(initSize);
} //获取可用连接对象
poolConnection = getAvailableConnection(); //没有可用连接对象时,等待连接对象的释放或者创建新的连接对象使用
while (poolConnection == null) {
System.out.println("---------------等待连接---------------");
createConnection(stepSize);
poolConnection = getAvailableConnection();
if (poolConnection == null) {
TimeUnit.MILLISECONDS.sleep(30);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return poolConnection;
} //创建数据库连接
private void createConnection(int count) throws SQLException {
if (list.size() + count <= maxSize) {
for (int i = 0; i < count; i++) {
System.out.println("初始化了" + (i + 1) + "个连接");
Connection connect = DriverManager.getConnection(URL, USERNAME, PASSWORD);
PoolConnection pool = new PoolConnection(connect, true);
list.add(pool);
}
}
} // 获取可用连接对象
private PoolConnection getAvailableConnection() throws SQLException {
for (PoolConnection pool : list) {
if (pool.isStatus()) {
Connection con = pool.getConnect();
// 验证连接是否超时
if (!con.isValid(timeout)) {
Connection connect = DriverManager.getConnection(URL, USERNAME, PASSWORD);
pool.setConnect(connect);
}
pool.setStatus(false);
return pool;
}
}
return null;
}
}

相关的PropertiesUtils 工具类

public class PropertiesUtils extends Properties {

    private static final long serialVersionUID = 1L;

    //定义属性文件名称
private final static String PROPERTY_FILE = "datasource.properties"; private static PropertiesUtils propertiesHolder = null; private PropertiesUtils() {
if (propertiesHolder != null) {
throw new RuntimeException("此类是单例,已经存在实例化对象了。");
}
} public static PropertiesUtils getInstance() {
if (propertiesHolder == null) {
synchronized (PropertiesUtils.class) {
if (propertiesHolder == null) {
propertiesHolder = new PropertiesUtils();
try (InputStream input = propertiesHolder.getClass().getClassLoader().getResourceAsStream(PROPERTY_FILE)) {
propertiesHolder.load(input);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return propertiesHolder;
}
}

4、测试类

public class PoolTest
{
public static void main( String[] args )
{
DataSource source = new DataSourceImpl();
CountDownLatch latch = new CountDownLatch(3);
int i = 0; for(; i < 3; i++){
new Thread(new Runnable() {
@Override
public void run() {
PreparedStatement pre = null;
ResultSet result = null;
try {
PoolConnection connect = source.getDataSource();
String sql = "select * from LEVEL4 where LEVEL4_CODE like ?";
pre = connect.getConnect().prepareCall(sql);
pre.setString(1, "%3AL34812ABAA%");
// 执行查询,注意括号中不需要再加参数
result = pre.executeQuery();
while (result.next()) {
// 当结果集不为空时
System.out.println("LEVEL4_CODE: " + result.getString("LEVEL4_CODE"));
} TimeUnit.SECONDS.sleep(1);
connect.releaseConnect();
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} }
}).start();
} try {
latch.await();
System.out.println("-------结束-----------");
} catch (InterruptedException e) {
e.printStackTrace();
} }
}

Oracle JDBC 连接池的更多相关文章

  1. 四大流行的jdbc连接池之C3P0篇

    C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSourc ...

  2. 【JDBC&Dbutils】JDBC&JDBC连接池&DBUtils使用方法(重要)

    -----------------------JDBC---------- 0.      db.properties文件 driver=com.mysql.jdbc.Driver url=jdbc: ...

  3. Spring+SpringMVC+MyBatis+easyUI整合优化篇(九)数据层优化-jdbc连接池简述、druid简介

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

  4. JDBC连接池-C池3P0连接

    JDBC连接池-C3P0连接 c3p0连接池的学习英语好的看英文原版      c3p0 - JDBC3 Connection and Statement Pooling 使用c3p0连接池  三种方 ...

  5. JDBC连接池(三)DBCP连接池

    JDBC连接池(三)DBCP连接池 在前面的随笔中提到 了  1.JDBC自定义连接池  2. C3P0连接池 今天将介绍DBCP连接池 第一步要导入jar包   (注意:mysql和mysql 驱动 ...

  6. JDBC连接池-自定义连接池

    JDBC连接池 java JDBC连接中用到Connection   在每次对数据进行增删查改 都要 开启  .关闭  ,在实例开发项目中 ,浪费了很大的资源 ,以下是之前连接JDBC的案例 pack ...

  7. Jmeter(九)JDBC连接池

    JDBC为java访问数据库提供通用的API,可以为多种关系数据库提供统一访问.因为SQL是关系式数据库管理系统的标准语言,只要我们遵循SQL规范,那么我们写的代码既可以访问MySQL又可以访问SQL ...

  8. jdbc连接池&改进dbUtil成C3P0Util

    一.jdbc连接池 1.连接池的存在理由   前面介绍的dbUtils工具类虽然实现了一个对jdbc的简单封装.但它依旧采取从驱动管理获取连接 (DriverManager.getConnection ...

  9. Oracle JDBC连接服务名、SID和tnsnames.ora配置的多种方式

    昨天,领导安排去新服务器上部署项目,给了我数据库地址,服务名称,端口,用户名和密码.结果数据库一直连接不上,日志中的错误提示是监听未找到SID,我才明白原来我jdbc.properties中需要的是S ...

随机推荐

  1. C++ ifstream ofstream 注意事项

    很久没写C++,已经完全不会写了... 在使用ifstream读取一个二进制文件时,发现读取的内容和源文件不相同,导致数据解析失败,于是尝试把用ifstream读取的内容用ofstream写入另一个文 ...

  2. Invariant Violation: requireNativeComponent: "RNCWKWebView" was not found in the UIManager.

    react-native  0.60以上版本安装第三方库的时候会autolink  出现这个问题是 我安装 react-native-webview 之后运行 ios出现的,这是因为ios 没有自动安 ...

  3. C++ 类再探

    关于类的一些遗漏的点. #include <iostream> #include <typeinfo> #include <string> using namesp ...

  4. js 概述 ( 一 )

    1 JS 概述 1 简称JS,是一种浏览器解释型语言,代码嵌套在HTML页面中,将由浏览器解释执行 作用:主要用来实现页面的动态效果,实现用户交互,实现网页中的网络请求 2 JS 组成 : 1 ECM ...

  5. Netty4实现JTT809对接

    网上的使用的netty版本过老,最近自己接触到这一块,重新写了一个 服务器流程 1,判定报文起始和结束标识 ,2去掉头尾标识进行转义,3,去掉CRC码进行CRC计算,4读取报文头,(5,如果加密则解密 ...

  6. Struts2 Action类的创建以及参数传递以及接收

    一.Struts中Action得创建方式 1,直接创建一个简单的Action类 添加Struts.xml,配置转发方法返回转发的页面. 2,实现一个Action类 Strust.xml配置对应的Url ...

  7. PHP数组赋值

    <?php $array1 = array('a','b'); $array2 = array('a'=>array('1','2'),'b'=>array('3','4')); $ ...

  8. 微信小程序将图片数据流添加到image标签中

    原文:https://blog.csdn.net/OliveLao/article/details/78136121 ---------------------------------------- ...

  9. WCF之.NET Remoting通讯

    一.NET Remoting 介绍 简介 .NET Remoting与MSMQ不同,它不支持离线可得,另外只适合.NET平台的程序进行通信.它提供了一种允许对象通过应用程序域与另一个对象进行交互的框架 ...

  10. SIGAI深度学习第六集 受限玻尔兹曼机

    讲授玻尔兹曼分布.玻尔兹曼机的网络结构.实际应用.训练算法.深度玻尔兹曼机等.受限玻尔兹曼机(RBM)是一种概率型的神经网络.和其他神经网络的区别:神经网络的输出是确定的,而RBM的神经元的输出值是不 ...