1、什么是数据库连接池
我们现在在开发中一定都会用到数据库,为了提高我们的系统的访问速度,数据库优化是一个有效的途径。
我们现在开发中使用数据库一般都要经历以下的四个步骤:
(1)加载数据库的驱动类,
(2)建立数据库连接,
(3)进行数据操作,
(4)关闭数据库连接;
在这四步中建立数据库连接是一个比较耗时的操作,如果每次有新的操作数据库的需求都去重新建立数据库连接必然要耗费一部分时间,拖慢系统的访问速度;在这种情况下我们就需要数据库连接池,预先创建好一定数量的数据库连接,等我们现需要使用时直接从其中拿已经创建好了尚未使用的的数据库连接,这样就可以节省掉一部分时间,加快系统的访问速度,保存这些预先创建的一定数量的数据库连接的容器称之为数据库连接池。
2、现有的常用数据库连接池
(1)DBCP数据库连接池
(2)C3P0数据库连接池
3、数据库连接池原理
数据库连接池通过预先创建一定数量的空闲的数据库连接,在需要数据库连接时直接从其中获取,而不要去重新创建而节省一定的时间。
数据库连接池的连接有连个属性,一个是本数据库的真正的连接对象,一个是标志本连接是否是空闲的标志;当数据库连接池被初始化的时候,会去创建一定数量(一般在配置文件中配置)的数据库连接,并且这些连接都是处于空闲状态的,当需要数据库连接时,直接从数据库连接池中获取已经创建并且空闲的数据库连 接 并将其致为非空闲状态,如果数据库连接池中没有了空闲的连接,则去看数据库连接池连接数量是否以达到最大值(一般在配置文件中配置),如果没有达到最 大 值则再去创建一定数量的空闲连接;当连接使用完毕后,并不真正的关闭连接,而是将连接的状态重新致为空闲。从而达到连接重复使用的效果,节省时间。
4、简易数据库连接池的实现
(1)、创建数据库连接池的对象,对象包括真正的数据库连接池对象和是否可用的标志。
importjava.sql.Connection; importjava.sql.ResultSet; importjava.sql.SQLException; importjava.sql.Statement; /*** 数据库连接池对象*/publicclassSimplePoolEntity { //真正的数据库连接对象privateConnectionconnection; //是否可用的标志,默认为true 可用privatebooleanisUsable=true; publicConnectiongetConnection() { returnconnection; } publicvoidsetConnection(Connectionconnection) { this.connection=connection; } publicbooleanisUsable() { returnisUsable; } publicvoidsetUsable(booleanusable) { isUsable=usable; } /*** 数据库操作方法* @param sql 需要执行的sql语句* @return ResultSet*/publicResultSetexecSql(Stringsql){ ResultSetrs=null; try { Statementstatement=connection.createStatement(); rs=statement.executeQuery(sql); } catch (SQLExceptione) { e.printStackTrace(); } returnrs; } }
(2)数据库连接池操作接口
/*** 数据库连接池操作接口*/publicinterfaceSimplePoolService { /*** 连接池创建连接接口* @param connCount 需要创建的连接数量*/voidcreateConnection(intconnCount) throwsException; /*** 获取数据库连接* @return* @throws Exception*/SimplePoolEntitygetConnection(); }
(3)数据库连接池操作实现
数据库连接池配置文件:
#数据库的驱动类simple.jdbc.driver=com.mysql.jdbc.Driver#数据库的连接urlsimple.jdbc.url=jdbc:mysql://localhost:3306/test#数据库的连接用户名simple.jdbc.username=root#数据库的连接密码simpel.jdbc.password=root#数据库连接池的初始化连接数量simple.init.count=10#数据库连接池的步进数量simple.step.count=4#连接池的最大数量simple.max.count=100
数据库连接池的实现
/**数据库操作实现本操作中将要实现数据库连接池的初始化工作,初始化参数采用配置文件的形式来进行配置 */publicclassSimplePoolServiceImplimplementsSimplePoolService { privateStringjdbcDriver; // 数据库驱动privateStringjdbcUrl; //数据库urlprivateStringusername; //用户名privateStringpassword; //密码privateIntegerinitCount; //初始化数量privateIntegerstepCount; //步进数量privateIntegermaxCount; //最大数量privateSimplePoolEntitysimplePoolEntity; privateSet<SimplePoolEntity>simplePoolEntitySet=newHashSet<>(); /*** 构造方法初始化 数据库连接池*/publicSimplePoolServiceImpl(){ init(); } /*** 数据库连接池初始化*/privatevoidinit(){ //1.读取配置文件InputStreamin=this.getClass().getClassLoader().getResourceAsStream("simpleboolconfig.properties"); Propertiesproperties=newProperties(); try { properties.load(in); //设置初始化参数jdbcDriver=properties.getProperty("simple.jdbc.driver"); jdbcUrl=properties.getProperty("simple.jdbc.url"); username=properties.getProperty("simple.jdbc.username"); password=properties.getProperty("simpel.jdbc.password"); initCount=Integer.parseInt(properties.getProperty("simple.init.count")); stepCount=Integer.parseInt( properties.getProperty("simple.step.count")); maxCount=Integer.parseInt( properties.getProperty("simple.max.count")); //加载数据库驱动Driverdriver= (Driver) Class.forName(jdbcDriver).newInstance(); //获取数据库管理对象DriverManager.deregisterDriver(driver); //初始化一定数量的连接createConnection(initCount); } catch (Exceptione) { e.printStackTrace(); } } publicvoidcreateConnection(intconnCount) throwsException { //判断数据库连接池是否以达到最大连接数if(simplePoolEntitySet.size() +connCount>maxCount){ thrownewRuntimeException("连接池数量已到上限"); } for (inti=0;i<connCount;i++){ simplePoolEntity=newSimplePoolEntity(); simplePoolEntity.setConnection(DriverManager.getConnection(jdbcUrl,username,password)); simplePoolEntity.setUsable(true); simplePoolEntitySet.add(simplePoolEntity); } } publicSimplePoolEntitygetConnection() { try { SimplePoolEntitysimplePoolEntity=getRealConection(); //为空时创建新的连接while (simplePoolEntity==null){ createConnection(stepCount); //创建连接比较耗时,建议在此处让线程延迟一定时间Thread.sleep(3000); simplePoolEntity=getRealConection(); } } catch (Exceptione) { e.printStackTrace(); } returnsimplePoolEntity; } privateSimplePoolEntitygetRealConection() throwsException{ //循环连接池,获取连接for(SimplePoolEntitysimplePoolEntity : simplePoolEntitySet){ //判断是否为空闲if(simplePoolEntity.isUsable()){ //判断连接是否有效if(!simplePoolEntity.getConnection().isValid(3000)){ //无效连接,重新创建连接替换该连接ConnectionrealConnect=DriverManager.getConnection(jdbcUrl,username,password); simplePoolEntity.setConnection(realConnect); } //设置状态为不可用simplePoolEntity.setUsable(false); returnsimplePoolEntity; } } returnnull; } }
(4) 对外提供单例模式的数据库连接池管理对象
publicclassSimplePoolManger { //私有化构造,禁止创建 privateSimplePoolManger(){} //在静态内部类中实例化对象,达到懒汉单例模式privatestaticclassClassLoad{ publicstaticSimplePoolServicegetSimplePoolService(){ returnnewSimplePoolServiceImpl(); } } publicstaticSimplePoolServicegetInstace(){ returnClassLoad.getSimplePoolService(); } }