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. (详细)JAVA使用JDBC连接MySQL数据库(2)- MySQL Connectors

    欢迎任何形式的转载,但请务必注明出处. 本节内容 mysql connectors介绍 下载安装 在java中配置 点击进入官网下载 一.mysql connectors介绍 mysql connec ...

  2. 串口工具kermit(ubuntu)

    安装 # sudo apt-get install ckermit 配置 kermit启动时,会首先查找~/.kermrc,然后再遍历/etc/kermit/kermrc # vi /etc/kerm ...

  3. IntelliJ IDEA控制台启动Tomcat输出中文乱码问题

    IntelliJ IDEA控制台输出中文乱码问题 1. 先解决Tomcat中文乱码问题 参考  Tomcat 输出日志出现中文乱码 2. 解决Idea配置问题 打开IntelliJ IDEA本地安装目 ...

  4. MySQL表的修改

    修改表的名字 ALTER TABLE 旧表名 RENAME 新表名; 字段的修改: 添加字段 ALTER TBALE 表名 ADD COLUMN 新字段 INT; 删除字段 ALTER TBALE 表 ...

  5. 跨域详解之jsonp,底层的实现原理

    分享一下跨域,不仅是因为现在的工作中遇到的越来越多,而且在面试中也经常被问到. 那么什么是跨域呢,我们来看官方给出的解释:浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的(所谓同源是指,域名 ...

  6. vs看源代码

    资源地址:https://www.cnblogs.com/HouZhiHouJueBlogs/p/4274197.html 资源地址:http://referencesource.microsoft. ...

  7. Fillder的前后端的应用

    测试需求:有一个功能,允许用钻石兑换金币,假设1钻石=1金币,前端控制一次至少兑换10个,最多100个,后台不做验证. 测试方案:输入10,也就是告诉前端我要兑换10个金币,等前端验证通过之后,截取要 ...

  8. 【ZZNU-oj-2116:人间不值得】(1亿以内的货币拼音转数值求折扣价原价)--hash+String大法好+字符串处理+超大暴力模拟题

    B : 人间不值得 概览问题列表状态排名编辑 Progress Bar 时间限制:1 Sec 内存限制:256 MiB提交:146 答案正确:12 提交 编辑 题目描述 家缠万贯来几时,我今停杯一问之 ...

  9. linux实操_shell判断语句

    常用判断条件: (1)两个数的比较 = 字符串的比较 -lt 小于 -le 小于等于 -eq 等于 -gt 大于 -ge 大于等于 -ne 不等于 (2)按照文件权限进行判断 -r 有读的权限 -w ...

  10. MySQL之text字段

    TEXT类型一般分为 TINYTEXT(255长度).TEXT(65535). MEDIUMTEXT(int最大值16M),和LONGTEXT(long最大值4G)这四种,它被用来存储非二进制字符集, ...