数据库连接池之c3p0与dbcp
今天上班早上闲得无聊,在非web项目下,用了下c3p0和dbcp 2个第三方数据库连接池,也学习到了点东西。顺赞每周三早上的早点,今天是鸡蛋汉堡+果汁,赞!
以前使用数据库连接池,是在Trilogy实习的时候,Spring+Hibernate+c3p0那套配置,后来继续用到软工、J2EE大程中,挺好,但也因此没有更多的熟悉到数据库连接池。昨天ebay buddy给的任务是,做一个小爬虫,爬1500个网页正则出所需数据,存入数据库,一开始没有用连接池,直接的JDBC问题也不大,基本上时间消耗是在HTTP连接上的。今天尝试着换连接池,看看效果,一开始脱离了Hibernate那套配置方法还真不会写的,没关系,百度嘛~
其实很简单,以c3p0为例,就是新建一个com.mchange.v2.c3p0.ComboPooledDataSource类,然后将相应的配置信息(比如DB的用户名密码,连接池的一些属性,譬如连接最大值最小值等等)传给它就好了,有2种方式,可以用它提供的API依次将配置信息置入,当然推荐使用properties的方式,然后将其封装在Properties类中,然后就可以从类中读出每个配置值放入数据源,这样整个项目有可以动态地改变配置信息而不用修改源代码即不用再次build the project。这边比较奇怪的是,ComboPooledDataSource有一个方法是setProperties(),但是扔进去正确的Properties对象后,仍然无法启动c3p0,我只能一一将Properties中的属性值取出然后用相应API置入。剩下的就是把这个数据源用一个Singleton形式包装起来,对外提供一个getConnection()的API就可以了,很方便。
dbcp也是一样,就是数据源类换成了org.apache.commons.dbcp.BasicDataSource,其余都一样,新建数据源,将配置信息植入,Singleton封装。
2个很有名的连接池都什么区别呢?想想dbcp可以开源界首屈一指的Apache下的项目,其地位可见一斑,但自己因为Hibernate的因素一直在用c3p0,于是就做了一下测试。数据库一个表930条记录,分别让2个连接池和纯的JDBC做930次查询,结果为:c3p0(2秒半不到一点),dbcp(1秒半多一点),jdbc(9秒半)。首先看到是使用了连接池后性能巨大的改善,其次dbcp速度要比c3p0要快一点,其他就没法从这次简单的测试用体现出来了。然后上网查了下,dbcp速度的确要快一点,不过貌似在并发量很大的情况下c3p0能逼近,但是BUG比较多,而且在稳定性上,dbcp就不如c3p0了,最有力的证据是Hibernate官方的申明:
Guys, after many problems with DBCP, I have decided to remove built in support for DBCP from Hibernate3, and deprecate DBCP in Hibernate 2.1. I advise everyone to migrate away from DBCP
to something that actually works, like C3P0 or Proxool.
(If you /must/ use DBCP, you can always write your own connection provider.)
Actually, it is probably about time we remove any remaining dependencies to
Apache commons stuff, since historically they have caused just /so/ much trouble. The only Apache things that do seem to work very well are Ant and log4j.
Even commons-logging is a PIA, especially in Tomcat.
Hibernate貌似把Apache说的很惨,这个当然是见仁见智,我觉得Apache绝大多数的项目是很成功的,当然具体选用哪种连接池还是要针对具体项目而言的,或者说能自己开发一个连接池是最好的,熟悉并且能针对项目做相应改进。