JDBC-运用连接池技术

一、什么是数据库连接池?

          官方:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
        个人理解:创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度,还更加安全可靠。

二、数据库连接池的运行机制

(1)  程序初始化时创建连接池
(2) 使用时向连接池申请可用连接
(3) 使用完毕,将连接返还给连接池
(4) 程序退出时,断开所有连接,并释放资源

三、分析

       程序开发过程中,存在很多问题:首先,每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。

       上述的用户查询案例,如果同时有1000人访问,就会不断的有数据库连接、断开操作:

 

       通过上面的分析,我们可以看出来,“数据库连接”是一种稀缺的资源,为了保障网站的正常使用,应该对其进行妥善管理。其实我们查询完数据库后,如果不关闭连接,而是暂时存放起来,当别人使用时,把这个连接给他们使用。就避免了一次建立数据库连接和断开的操作时间消耗。原理如下:

四、技术演进出来的数据库连接池

       由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道,对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。

 总结:

         连接池:
           程序每一次与数据库请求连接或者是关闭连接,都会造成很大的内存消耗。需要尽量避免这种大的 开 销。而连接池技术,是在程序启动时, 与数据库连接时,创建好一定数量的连接。 当真正需要连接时,程序 会连接池中寻找空闲的连接。 不使用时,会归还给连接池。当连接池中的空闲连接小于 一定数量时,连接池会 创建一批新的连接。就避免了程序 与数据库之间的直接连接和关闭。   

 DBCP连接池的使用: 

         作为开源的数据库连接池,C3P0是一个优秀的连接池,性能也十分可靠。

连接数据库的连接池技术

部分代码:

package util;

import java.io.File;
import java.io.FileReader;
import java.sql.Connection;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
/**
 * 使用线程池管理连接,关闭等方法
 */
public class DBUtil3 {
	private static String driver;
	private static String url;
	private static String user;
	private static String pwd;
	
	//创建连接池对象
	private static BasicDataSource bds = new BasicDataSource();//连接池技术
	//使用线程池管理:此线程池只管理一个连接池	
	private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
	static{
		try {
			FileReader fr = new FileReader("p"+File.separator+"db.properties");
			Properties prop = new Properties();
			prop.load(fr);
			
			driver = prop.getProperty("driver");
			url = prop.getProperty("url");
			user = prop.getProperty("user");
			pwd = prop.getProperty("pwd");
	
			//给连接池设置参数
			bds.setDriverClassName(driver);
			bds.setUrl(url);
			bds.setUsername(user);
			bds.setPassword(pwd);
			
			//初始化连接数
			bds.setInitialSize(5);
			//最大活跃数
			bds.setMaxActive(8);
			//最大空闲连接数
			bds.setMaxIdle(4);
			//最小空闲连接数
			bds.setMinIdle(1);
			//最大等待时间:毫秒
			bds.setMaxWait(30);
			
			Class.forName(driver);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static synchronized Connection getConnection(){
		Connection conn = null;
		try {
			conn = tl.get();
			if(conn==null){
				conn = bds.getConnection();
				tl.set(conn);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}	
	public static synchronized void closeConnection(){
		try {
			Connection conn = tl.get();
			if(conn!=null){
				//断开连接,归还给连接池
				conn.close();
				//清空
				tl.set(null);
				//tl.remove();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		System.out.println(getConnection());
	}	
}
db.properties配置文件
        driver=oracle.jdbc.driver.OracleDriver
        #driver=oracle.jdbc.OracleDriver
        url=jdbc:oracle:thin:@localhost:1521:orcl
        user=scott
        pwd=1234



猜你喜欢

转载自blog.csdn.net/xiaozelulu/article/details/80254879