您好,欢迎访问三七文档
一、数据库连接池1.什么是连接池传统的开发模式下,Servlet处理用户的请求,找Dao查询数据,dao会创建与数据库之间的连接,完成数据查询后会关闭数据库的链接。这样的方式会导致用户每次请求都要向数据库建立链接而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、宕机。解决方案就是数据库连接池连接池就是数据库连接对象的一个缓冲池我们可以先创建10个数据库连接缓存在连接池中,当用户有请求过来的时候,dao不必创建数据库连接,而是从数据库连接池中获取一个,用完了也不必关闭连接,而是将连接换回池子当中,继续缓存使用数据库连接池可以极大地提高系统的性能2.实现数据库连接池jdbc统一了数据库的操作定义了规范jdbc针对数据库连接池也定义的接口java.sql.DataSource,所有的数据库连接池实现都要实现该接口该接口中定义了两个重载的方法ConnectiongetConnection()ConnectiongetConnection(Stringusername,Stringpassword)数据库连接池实现思路1)定义一个类实现java.sql.DataSource接口2)定义一个集合用于保存Connection对象,由于频繁地增删操作,用LinkedList比较好3)实现getConnection方法,在方法中取出LinkedList集合中的一个连接对象返回注意:返回的Connection对象不是从集合中获得,而是删除用户用完Connection,会调用close方法释放资源,此时要保证连接换回连接池,而不是关闭连接重写close方法是难点,解决方案:装饰设计模式、动态代理二、数据源通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。一些开源组织提供了数据源的独立实现,常用的有:DBCP数据库连接池C3P0数据库连接池1.DBCP数据源介绍DBCP是Apache软件基金组织下的开源连接池实现tomcat服务器就是使用DBCP作为数据库连接池使用DBCP数据源,需要导入两个jar包Commons-dbcp.jar:连接池的实现Commons-pool.jar:连接池实现的依赖库DBCP核心APIBasicDataSource数据源实现BasicDataSourceFactory用于创建数据源的工厂类dbcp创建连接池方法1:直接创建对象,设置参数BasicDataSourcebds=newBasicDataSource();//设置连接数据库需要的配置信息bds.setDriverClassName(com.mysql.jdbc.Driver);bds.setUrl(jdbc:mysql://localhost:3306/jdbc3);bds.setUsername(root);bds.setPassword(root);//设置连接池的参数bds.setInitialSize(5);bds.setMaxActive(10);ds=bds方法2:通过工厂类创建对象,读取配置文件try{Propertiesprop=newProperties();//读配置文件InputStreamin=JdbcUtils.class.getClassLoader().getResourceAsStream(dbcpconfig.properties);prop.load(in);ds=BasicDataSourceFactory.createDataSource(prop);}catch(Exceptione){thrownewExceptionInInitializerError(e);}配置文件为dbcpconfig.properties#连接设置driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/jdbc3username=rootpassword=root#!--初始化连接--initialSize=5#最大连接数量maxActive=10#!--最大空闲连接--maxIdle=10#!--超时等待时间以毫秒为单位6000毫秒/1000等于60秒--maxWait=60000#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]#注意:user与password两个属性会被明确地传递,因此这里不需要包含他们。connectionProperties=useUnicode=true;characterEncoding=gbk#指定由连接池所创建的连接的自动提交(auto-commit)状态。defaultAutoCommit=true#driverdefault指定由连接池所创建的连接的只读(read-only)状态。#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)defaultReadOnly=#driverdefault指定由连接池所创建的连接的事务级别(TransactionIsolation)。#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLEdefaultTransactionIsolation=READ_UNCOMMITTED2.C3P0数据源介绍c3p0是一个开源的jdbc连接池,我们熟悉的Hibernate和Sprint框架使用的都是该数据源创建连接池对象方法1:直接创建对象,设置参数ComboPooledDataSourcecpds=newComboPooledDataSource();cpds.setDriverClass(com.mysql.jdbc.Driver);cpds.setJdbcUrl(jdbc:mysql://localhost:3306/jdbc3);cpds.setUser(root);cpds.setPassword(root);cpds.setInitialPoolSize(5);cpds.setMaxPoolSize(15);方法2:读取配置文件ComboPooledDataSourcecpds=newComboPooledDataSource(itcast);配置文件为c3p0-config.xml该文件需要放在类路径下c3p0-configdefault-config!—-默认配置–-propertyname=initialPoolSize5/propertypropertyname=maxPoolSize15/propertypropertyname=driverClasscom.mysql.jdbc.Driver/propertypropertyname=jdbcUrljdbc:mysql://localhost:3306/jdbc3/propertypropertyname=userroot/propertypropertyname=passwordroot/property/default-confignamed-configname=xwhpropertyname=initialPoolSize5/propertypropertyname=maxPoolSize15/propertypropertyname=driverClasscom.mysql.jdbc.Driver/propertypropertyname=jdbcUrljdbc:mysql://localhost:3306/jdbc3/propertypropertyname=userroot/propertypropertyname=passwordroot/property/named-config/c3p0-config三、ResultSetMetaData对象元数据,可以理解为描述数据的数据jdbc中的元数据是指数据库、表、列的定义信息ResultSetMetaData对象表示结果集ResultSet对象的元数据获得该对象:ResultSetMetaDatametaData=rs.getMetaData();常用方法:getColumnCount()返回resultset对象的列数getColumnName(intcolumn)获得指定列的名称getColumnTypeName(intcolumn)获得指定列的类型四、jdbc优化使用jdbc对数据库进行crud操作时,会有很多重复的代码,仔细分析不难发现其实变化的只是其中几行代码对于cud(增删改)操作,代码几乎完全一样,唯一的区别就是sql语句不同,我们完全可以把相同的代码抽取出来定义在一个工具方法中,然后定义一个参数来接收sql语句对于r(查询)操作,除SQL语句不同之外,根据操作的实体不同,对ResultSet结果集的处理也有所不相同,因此可义一个query方法,除以参数形式接收变化的SQL语句外,可以使用策略模式由qurey方法的调用者决定如何把ResultSet中的数据映射到实体对象中优化后的工具类JdbcUtils//通用的增删改方法publicstaticintupdate(Stringsql,Object[]params)throwsSQLException{Connectionconn=null;PreparedStatementpstmt=null;ResultSetrs=null;try{//获得连接conn=getConnection();//预编译sqlpstmt=conn.prepareStatement(sql);//将参数设置进去for(inti=0;params!=null&&iparams.length;i++){pstmt.setObject(i+1,params[i]);}//发送sqlintnum=pstmt.executeUpdate();returnnum;}finally{//释放资源release(conn,pstmt,rs);}}//优化查询publicstaticObjectquery(Stringsql,Object[]params,ResultSetHandlerrsh)throwsSQLException{Connectionconn=null;PreparedStatementpstmt=null;ResultSetrs=null;try{//获得连接conn=getConnection();//预编译sqlpstmt=conn.prepareStatement(sql);//将参数设置进去for(inti=0;params!=null&&iparams.length;i++){pstmt.setObject(i+1,params[i]);}//发送sqlrs=pstmt.executeQuery();//不知道别人想如何处理结果集//干脆想别人所要一个结果集的处理器//为了让当前代码继续,定义一个结果集处理器接口//策略模式,规定算法,具体的算法留给将来的调用者实现Objectobj=rsh.handle(rs);returnobj;}finally{//释放资源release(conn,pstmt,rs);}}结果集处理器接口publicinterfaceResultSetHandler{//处理结果集的方法publicObjecthandle(ResultSetrs);}实现类:BeanListHandlerpublicclassBeanListHandl
本文标题:什么是数据库连接池
链接地址:https://www.777doc.com/doc-3378306 .html