0
点赞
收藏
分享

微信扫一扫

两种开源的数据库连接池

两种开源的数据库连接池



JDBC 的数据库连接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口,该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:



DBCP 数据库连接池



C3P0 数据库连接池



DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把 DataSource 称为连接池





DBCP 数据源



DBCP 是 Apache 软件基金组织下的开源连接池实现,该连接池依赖该组织下的另一个开源系统:Common-pool. 如需使用该连接池实现,应在系统中增加如下两个 jar 文件:



Commons-dbcp.jar:连接池的实现



Commons-pool.jar:连接池实现的依赖库





使用cbcp数据源,当数据库访问结束后,程序还是像以前一样关闭数据库连接:conn.close(); 但上面的代码并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。



具体的使用代码例子如下:



所有数据库连接在一个xml文件中配置,文件内容如下



username=root



password=1234





#初始化连接



initialSize=10





#最大连接数量



maxActive=50





#最大空闲连接



maxIdle=20





#最小空闲连接



minIdle=5





#超时等待时间以毫秒为单位 6000毫秒/1000等于60秒



maxWait=60000





#指定由连接池所创建的连接的自动提交(auto-commit)状态。



defaultAutoCommit=true





#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]



#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。



connectionProperties=useUnicode=true;characterEncoding=gbk





#driver default 指定由连接池所创建的连接的只读(read-only)状态。



#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)



defaultReadOnly=





#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。



#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE



defaultTransactionIsolation=READ_COMMITTED





而具体获得连接的代码:



Properties props = new Properties();



从上面的xml文档中读取数据库连接需要的各种数据props.load(TestDBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"));



获得DataSource对象



DataSource ds = BasicDataSourceFactory.createDataSource(props);



从数据库连接池中获得连接



Connection conn = ds.getConnection();



并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。



conn.close();







使用c3p0数据源



首先,加载“c3p0-0.9.1.2.jar”



然后具体的使用代码示范如下:



ComboPooledDataSource cpds = new ComboPooledDataSource();



cpds.setUser("root");



cpds.setPassword("123");



cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test");



cpds.setDriverClass("com.mysql.jdbc.Driver");



//设置初始化连接数



cpds.setInitialPoolSize(10);



//最大连接数量



cpds.setMaxPoolSize(50);



//最小连接



cpds.setMinPoolSize(20);



//超时等待时间以毫秒为单位 6000毫秒/1000等于60秒



cpds.setMaxIdleTime(60000);



Connection conn = cpds.getConnection();









Tomcat数据库连接池的配置



DataSource对象可由容器(Tomcat)提供,不能使用创建实例的方法来生成DataSource对象,要采用JAVA的JNDI。





JNDI(Java Naming and Directory Interface,Java命名和目录接口)是一些标准API接口,Java程序通过这些API可以访问命名目录服务。而命名目录服务将名称和对象联系起来,使得可以用名称访问对象。



JNDI的定义不依赖于任何独立的命名目录服务器,对于各种命名目录服务器,都可通过统一的JNDI接口调用。



JNDI在系统运行时会在内存中构建这个一个层次结构。通过程序访问到这个JNDI管理器的InitialContext对象就拥有了这个JNDI的上下文,就可以查找要用的对象,并使用它





JNDI接口概述



Context:javax.naming的核心接口,指定了命名上下文。定义了基本的操作,例如添加一个名称-对象的绑定,查找绑定到特定名称的对象,显示绑定列表,移除名称-对象绑定,创建或者销毁相同类型的上下文等



//从服务器上连接



Context ctx=new InitialContext()



Context.lookup():检索指定的对象





为了使用JNDI,需要实现做两个工作



1.写context.xml文档,并放置到META-INF目下



2.在tomcat服务器的lib目录下复制上数据库驱动的jar包





<?xml version="1.0" encoding="UTF-8"?>



<Context>



<Resource



指定Resource的JNDI的名字



name="testdatasource"



Container:表示由容器来负责创建和管理 Application:表示由web应用来创建和管理



auth="Container"



type="javax.sql.DataSource"



maxActive="100"



maxIdle="30"



maxWait="10000"



username="root"



password="5131"



driverClassName="com.mysql.jdbc.Driver"



url="jdbc:mysql://localhost:3306/itcast"/>





</Context>







Tomcat提供了一个与JavaEE应用服务相兼容的JNDI--InitialContext实现实例(把DataSource作为一种可配置的JNDI资源来处理)。所有的入口和资源都放在JNDI命名空间里的java:comp/env段里。





获得数据库连接的具体代码:(注意,这个时候数据库连接只能通过tomcat服务器来获取,所以这些代码只能写在tomcat可以访问到的部分,比如jsp页面或者servlet)



Context context = new InitialContext();



后面红色部分要和context.xml中配置的“name”属性一致



DataSource ds =(DataSource)context.lookup("java:comp/env/testdatasource");









Org.apache.commons.dbutils的使用



先解释一段代码:



import org.apache.commons.dbutils.QueryRunner;





QueryRunner run = new QueryRunner();



list = (List) run.query(conn, sql, new BeanListHandler(clazz));



这里的run.query(conn, sql, new BeanListHandler(clazz))就可以返回一个查询对象的list,其中的“new BeanListHandler(clazz)”是一个实现了ResultSetHandler接口的对象。其中传入的clazz对象是需要被放入List的实体对象的JavaBean对象。比如下面的使用方法



//param 1: 数据库连接



// 2: 查询数据库用的 sql



// 3: 替换 sql 中的参数数组



// 4: 如何处理得到的结果集



List list = (List) run.query(conn, sql, params, new BeanListHandler(Customer.class));



最后得到的List就是一个Customer对象集合,dbutils会自动把查询到的结果放置到Customer类的对象中。





关于ResultSetHandler接口,前面看到的 BeanListHandler(Customer.class)实际上就是实现了这个接口,在这个接口内部只有一个方法:



public Object handle(ResultSet rs) throws SQLException



可以看到,这个方法中传入的参数就是执行sql后的结果集合,而我们用的这个BeanListHandler类其实就是实现了这个方法,拿到处理的结果集以后,根据传入的javaBean的class对象利用内省把查询到的数据放置到这个javabean的对象中。





作为示范,我们自己实现一个





//使用自定义的 ResultSetHandler 对象



list = (List) run.query(conn, sql, params,



自定义一个实现ResultSetHandler接口的匿名对象



new ResultSetHandler(){





实现接口中的方法,获得结果集中的数据,自己装入对象并装入list中。



public Object handle(ResultSet rs) throws SQLException {



List list = new ArrayList();



while(rs.next()){



int id = rs.getInt(1);



String name = rs.getString(2);



String address = rs.getString(3);



String phone = rs.getString(4);





Customer cust = new Customer();



cust.setAddress(address);



cust.setId1(id);



cust.setName(name);



cust.setPhone(phone);





list.add(cust);



}





return list;



}





});





利用Org.apache.commons.dbutils中的方法,我们可以非常方便的进行JDBC的操作。



比如



下面代码可以执行所有的数据修改操作,只需要传入sql和参数,还有connection就可以了





public void update(Connection conn, String sql, Object [] params, String exceptionMsg){



QueryRunner run = new QueryRunner();



try {



run.update(conn, sql, params);



} catch (SQLException e) {



e.printStackTrace();



throw new RuntimeException(exceptionMsg);



}



}







public Object getObject(Connection conn, String sql, Object [] prams, Class clazz, String exceptionMsg){



List list = null;





QueryRunner run = new QueryRunner();



try {



list = (List) run.query(conn, sql, prams, new BeanListHandler(clazz));



} catch (SQLException e) {



e.printStackTrace();



throw new RuntimeException(exceptionMsg);



}





if(list != null)



return list.get(0);



else



return null;



}







public List getConditionObjects(Connection conn, String sql, Object [] prams, Class clazz, String exceptionMsg){



List list = null;





QueryRunner run = new QueryRunner();



try {



list = (List) run.query(conn, sql, prams, new BeanListHandler(clazz));



} catch (SQLException e) {



e.printStackTrace();



throw new RuntimeException(exceptionMsg);



}





return list;



}


举报

相关推荐

0 条评论