JDBC (Java DataBase Connectivity)数据库连接池原理解析与实现
一、应用程序直接获取数据库连接的缺点
用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。
二、使用数据库连接池优化程序性能
数据库连接池的基本概念
数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池正式针对这个问题提出来的.数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中, 这些数据库连接的数量是由最小数据库连接数来设定的.无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量.连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中.
数据库连接池的最小连接数和最大连接数的设置要考虑到以下几个因素:
最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.
最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作
如果最小连接数与最大连接数相差很大:那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接.不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,他将被放到连接池中等待重复使用或是空间超时后被释放.
编写数据库连接池
DBManage 这个类用来读取properties配置文件,创建connection对象,管理connection对象
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties; import orm.bean.Configuration;
import orm.pool.DBConnPool; /**
* 根据配置信息,维持连接对象的管理
* @author Haidnor
*
*/
@SuppressWarnings("all")
public class DBManage {
/**
* 配置信息
*/
private static Configuration conf; /**
* 连接池对象
*/
private static DBConnPool pool = null;
/**
* 初始化,加载指定的文件
*/
static {
Properties pros = new Properties(); try {
pros.load(Thread.currentThread().getContextClassLoader().getSystemResourceAsStream("database.properties"));
} catch (IOException e) {
e.printStackTrace();
}
conf = new Configuration(); //读取配置文件,将配置文件内的信息保存在配置对象中
conf.setDriver(pros.getProperty("driver"));
conf.setUrl(pros.getProperty("url"));
conf.setUser(pros.getProperty("user"));
conf.setPassword(pros.getProperty("password"));
conf.setUsingDB(pros.getProperty("usingDB"));
conf.setSrcPath(pros.getProperty("srcPath"));
conf.setPoPackage(pros.getProperty("poPackage"));
conf.setQueryClass(pros.getProperty("queryClass"));
conf.setPoolMinSize(Integer.parseInt(pros.getProperty("poolMinSize")));
conf.setPoolMaxSize(Integer.parseInt(pros.getProperty("poolMaxSize")));
} /**
* 在连接池中获得Connection对象
* @return
*/
public static Connection getConnetion() {
if(pool == null) {
pool = new DBConnPool();
}
return pool.getConnection();
} /**
* 创建新的Connection对象
* @return
*/
public static Connection createConnetion() {
try {
Class.forName(conf.getDriver());
return DriverManager.getConnection(conf.getUrl(),conf.getUser(),conf.getPassword()); //目前直接建立连接,后期加入连接池处理,提高效率
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 关闭数据库连接ResultSet Statement Connection
* @param rs
* @param pa
* @param conn
*/
public static void close(ResultSet rs,Statement pa,Connection conn){
if(conn != null){
pool.close(conn);
}
} /**
* 返回Configuration对象
* @return Configuration对象
*/
public static Configuration getConf(){
return conf;
}
}
数据库连接池类DBManage ,将多个Connection对象存放在一个List集合中。在程序初始化前,会自动根据配置文件中设置的连接池对象最小数,往list集合中创建多个Connection对象。
以后使用Connection对象就可以直接从list集合中获取。关闭Connection对象不再使用close()方法,而是将Connection对象再放回到list集合中。
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import orm.core.DBManage; /**
* 连接池类
* @author Haidnor
*
*/ public class DBConnPool { /**
* 连接池对象
*/
private List<Connection> pool; /**
* 最大连接数
*/
private static final int POOL_MAX_SIZE = DBManage.getConf().getPoolMaxSize(); /**
* 最小连接数
*/
private static final int POOL_MIN_SIZE = DBManage.getConf().getPoolMinSize(); /**
* 初始化连接池,使池中的连接数达到最小值
*/
private void initPool() {
if(pool == null) {
pool = new ArrayList<Connection>();
}
while(pool.size() <= DBConnPool.POOL_MIN_SIZE){
pool.add(DBManage.createConnetion());
}
} /**
* 从连接池中取出一个连接对象
* @return
*/
public synchronized Connection getConnection() {
int last_index = pool.size() - 1;
Connection connection = pool.get(last_index);
pool.remove(last_index);
return connection;
} /**
* 将连接放回池中
*/
public synchronized void close(Connection connection) {
if(pool.size() >= POOL_MAX_SIZE){
try {
if(connection != null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}else{
pool.add(connection);
}
} public DBConnPool(){
initPool();
} }
最后建立一个测试类。分别使用数据库连接池Connection对象和直接new Connection对象对数据库某个表进行3000次查询测试
使用连接池耗时952毫秒,不用连接池耗时12742毫秒。
import java.util.List; import orm.core.MySqlQuery;
import orm.po.User_yinbiao1; public class Test {
//不加连接池耗时 12742毫秒
//加连接池耗时:952毫秒
public static void main(String[] args) {
long a = System.currentTimeMillis();
for(int i=0; i<3000; i++){
testQueryRows();
}
long b = System.currentTimeMillis();
System.out.println("使用数据库连接池运行时间:" + (b - a) + "毫秒");
} public static void testQueryRows() {
List list = new MySqlQuery().queryRows("SELECT * FROM user_yinbiao1", User_yinbiao1.class, new Object[] {});
User_yinbiao1 user = (User_yinbiao1)list.get(2);
} }
JDBC (Java DataBase Connectivity)数据库连接池原理解析与实现的更多相关文章
- JDBC(Java Database Connectivity,Java数据库连接)API是一个标准SQL(Structured Query Language
JDBC(Java Database Connectivity,Java数据库连接)API是一个标准SQL(Structured Query Language,结构化查询语言)数据库访问接口,它使数据 ...
- [19/05/06-星期一] JDBC(Java DataBase Connectivity,java数据库连接)_基本知识
一.概念 JDBC(Java Database Connectivity)为java开发者使用数据库提供了统一的编程接口,它由一组java类和接口组成.是java程序与数据库系统通信的标准API. J ...
- SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC ...
- [19/05/05-星期日] JDBC(Java DataBase Connectivity,java数据库连接)_mysql基本知识
一.概念 (1).是一种开放源代码的关系型数据库管理系统(RDBMS,Relational Database Management System):目前有很多大公司(新浪.京东.阿里)使用: (2). ...
- [19/05/07-星期二] JDBC(Java DataBase Connectivity)_CLOB(存储大量的文本数据)与BLOB(存储大量的二进制数据)
一. CLOB(Character Large Object ) – 用于存储大量的文本数据 – 大字段有些特殊,不同数据库处理的方式不一样,大字段的操作常常是以流的方式来处理的.而非一般的字段,一次 ...
- [19/05/08-星期三] JDBC(Java DataBase Connectivity)_ORM(Object Relationship Mapping, 对象关系映射)
一.概念 基本思想: – 表结构跟类对应: 表中字段和类的属性对应:表中记录和对象对应: – 让javabean的属性名和类型尽量和数据库保持一致! – 一条记录对应一个对象.将这些查询到的对象放到容 ...
- JAVA和C#中数据库连接池原理与应用
JAVA和C#中数据库连接池原理 在现在的互联网发展中,高并发成为了主流,而最关键的部分就是对数据库操作和访问,在现在的互联网发展中,ORM框架曾出不穷, 比如:.Net-Core的EFCore.Sq ...
- JDBC数据库连接池原理
JDBC是java数据库连接的简称.它是一种用于实行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成.其相关的API都在java.sql.*包下 ...
- Java数据库连接池原理与简易实现
1.什么是数据库连接池 我们现在在开发中一定都会用到数据库,为了提高我们的系统的访问速度,数据库优化是一个有效的途径.我们现在开发中使用数据库一般都要经历以下的四个步骤:(1)加载数据库的驱动类,(2 ...
随机推荐
- oracle中Blob、Clob、Varchar之间的互相转换
以下是oracle中Blob.Clob.Varchar之间的互相转换(都是百度找的,亲测可用) Blob转Varchar2: CREATE OR REPLACE FUNCTION blob_to_va ...
- java CGLib代理
转载自 cglib之Enhancer 1. 背景 cglib库的Enhancer在Spring AOP中作为一种生成代理的方式被广泛使用.本文针对Enhancer的用法以实际代码为例作一些介绍. ...
- nginx文件服务器搭建
一.安装 (CentOS 7) yum install nginx -y 如果报错: [u3@L3 /]$ sudo yum install nginx -y Loaded plugins: fast ...
- 提取json字符串中指定格式中的参数值
直接上代码: import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; p ...
- opencv实现人脸识别(五) 运用tkinter进行GUI绘制 整合人脸识别模块
因为之前学习过tkinter库,所以在学习了人脸识别模块的编写后, 打算绘制一个简单的GUI来应用人脸识别功能. 主界面如下所示: 签到打开在点开后直接进行人脸识别,如果成功则自动关闭视频窗口. 录入 ...
- not or and 的优先级是不同的
not or and 的优先级是不同的: not > and > or 请用最快速度说出答案: not 1 or 0 and 1 or 3 and 4 or 5 and 6 or 7 an ...
- nginx 实践配置
nginx.conf文件 user root; worker_processes 1; error_log logs/error.log crit; #error_log logs/error.log ...
- Image Processing and Analysis_8_Edge Detection:Scale-space and edge detection using anisotropic diffusion——1990
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- Image Processing and Computer Vision_Review:Local Invariant Feature Detectors: A Survey——2007.11
翻译 局部不变特征探测器:一项调查 摘要 -在本次调查中,我们概述了不变兴趣点探测器,它们如何随着时间的推移而发展,它们如何工作,以及它们各自的优点和缺点.我们首先定义理想局部特征检测器的属性.接下来 ...
- 013.子查询和分页子查询(sql实例)
--1 子查询 如果子查询和表连接都实现的时候,推荐用表连接实现( 一般:能用表连接实现的就用表连接,有些情况用表连接不能 或者不易实现的再选择子查询) 系统:缓存,执行计划技术手段 --1 wher ...