一、应用程序直接获取数据库连接的缺点

  用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天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)数据库连接池原理解析与实现的更多相关文章

  1. JDBC(Java Database Connectivity,Java数据库连接)API是一个标准SQL(Structured Query Language

    JDBC(Java Database Connectivity,Java数据库连接)API是一个标准SQL(Structured Query Language,结构化查询语言)数据库访问接口,它使数据 ...

  2. [19/05/06-星期一] JDBC(Java DataBase Connectivity,java数据库连接)_基本知识

    一.概念 JDBC(Java Database Connectivity)为java开发者使用数据库提供了统一的编程接口,它由一组java类和接口组成.是java程序与数据库系统通信的标准API. J ...

  3. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析

    作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC ...

  4. [19/05/05-星期日] JDBC(Java DataBase Connectivity,java数据库连接)_mysql基本知识

    一.概念 (1).是一种开放源代码的关系型数据库管理系统(RDBMS,Relational Database Management System):目前有很多大公司(新浪.京东.阿里)使用: (2). ...

  5. [19/05/07-星期二] JDBC(Java DataBase Connectivity)_CLOB(存储大量的文本数据)与BLOB(存储大量的二进制数据)

    一. CLOB(Character Large Object ) – 用于存储大量的文本数据 – 大字段有些特殊,不同数据库处理的方式不一样,大字段的操作常常是以流的方式来处理的.而非一般的字段,一次 ...

  6. [19/05/08-星期三] JDBC(Java DataBase Connectivity)_ORM(Object Relationship Mapping, 对象关系映射)

    一.概念 基本思想: – 表结构跟类对应: 表中字段和类的属性对应:表中记录和对象对应: – 让javabean的属性名和类型尽量和数据库保持一致! – 一条记录对应一个对象.将这些查询到的对象放到容 ...

  7. JAVA和C#中数据库连接池原理与应用

    JAVA和C#中数据库连接池原理 在现在的互联网发展中,高并发成为了主流,而最关键的部分就是对数据库操作和访问,在现在的互联网发展中,ORM框架曾出不穷, 比如:.Net-Core的EFCore.Sq ...

  8. JDBC数据库连接池原理

    JDBC是java数据库连接的简称.它是一种用于实行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成.其相关的API都在java.sql.*包下 ...

  9. Java数据库连接池原理与简易实现

    1.什么是数据库连接池 我们现在在开发中一定都会用到数据库,为了提高我们的系统的访问速度,数据库优化是一个有效的途径.我们现在开发中使用数据库一般都要经历以下的四个步骤:(1)加载数据库的驱动类,(2 ...

随机推荐

  1. SQLite进阶-14.子查询

    目录 子查询 SELECT语句中的子查询 INSERT语句中的子查询 UPDATE语句中的子查询 DELETE语句中的子查询 子查询 子查询或内部查询或嵌套查询是在另一个SQLite查询内嵌入在WHE ...

  2. 【k8s第一步】Kubernetes-Linux系统初始化【已修正错误】

    ⒈配置Linux的IP地址 vim /etc/sysconfig/network-scripts/ifcfg-ens33v ifcfg-ens33是网卡的最新命名规范,它会从BIOS => PC ...

  3. BridgeOverARoughRiver(POJ-3404)【AdHoc】

    题目链接:https://vjudge.net/problem/POJ-3404 题意:n个极限速度不同的人要过桥,一开始所有人在桥的一边,每次最多两个人同时过桥,过桥时需要用一把火炬并且全场只有一把 ...

  4. easyUI datagrid 刷新取消加载信息 自动刷新闪屏问题

    <style type="text/css"> /*-- 消除grid屏闪问题 --//*/ .datagrid-mask { opacity: 0; filter: ...

  5. java的设计模式的一些链接,站在巨人的肩膀上,才能看的更远。(均来源与网上的各个大牛的博客中)

    创建型抽象工厂模式 http://www.cnblogs.com/java-my-life/archive/2012/03/28/2418836.html工厂方法 http://www.cnblogs ...

  6. 通过python的selenium实现网站自动登陆留言

    from selenium import webdriver import time driver = webdriver.Chrome() driver.get('https://wordpress ...

  7. vc 网络编程(socket)

    在网上找了很多的资料,现将这些资料整合起来,详细介绍一下VC下的socket编程,并提供一个服务器客户端具体的实例.希望对您有所帮助 一.原理部分 (个人觉得这篇写的可以,所以转与此,原文地址:htt ...

  8. LeetCode:197.上升的温度

    题目链接:https://leetcode-cn.com/problems/rising-temperature/ 题目 给定一个 Weather 表,编写一个 SQL 查询,来查找与之前(昨天的)日 ...

  9. react hooks学习

    接触React项目快两个月了,还在研究摸索各种知识点的过程中,充实且幸福. 在项目中学习新知识,还是很有效率的,一边写项目,一边实验新的知识点,比如react hooks!嘻嘻嘻~~~ 写了好一段时间 ...

  10. django 函数和类实现分页案例

    方法一: 模拟分页from django.shortcuts import render,HttpResponse from app01 import models def hostnames(req ...