1、使用org.springframework.jdbc.datasource.DriverManagerDataSource
说明:DriverManagerDataSource建立连接是只要有连接就新建一个connection,根本没有连接池的作用。
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>${jdbc.driverClassName}</value>
</property>
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>
DriverManagerDataSource:在每个连接请求时都新建一个连接。与DBCP的BasicDataSource不同,DriverManagerDataSource提供的连接没有进行池管理。
SingleConnectionDataSource:在每个连接请求时都返回同一个连接。虽然它不同严格意义上的池管理数据源,但我们可以把它看作只有一个连接的池。SingleConnectionDataSource只使用一个数据库连接,所以不适合用于多线程程序。而 DriverMangerDataSource虽然能够支持多线程,但它会在每次连接请求时都新建一个连接,这是以性能为代价的。由于这些限制,我们强烈建议应该使用数据源池。
目前常用的连接池有:DBCP、C3P0、Proxool
数据库连接池的最小连接数和最大连接数的设置要考虑到下列几个因素:
1) 最小连接数是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费;
2) 最大连接数是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。
3) 如果最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
2、使用org.apache.commons.dbcp.BasicDataSource
说明:这是一种数据源配置方式,它使用了连接池技术 。使用dbcp连接池需要导入相应的jar包,这里导入的是两个jar包:commons-dbcp-1.4.jar、commons-pool-1.5.6.jar、commons-collection.jar
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>Oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:orcl</value>
</property>
<property name="username">
<value>test</value>
</property>
<property name="password">
<value>test</value>
</property>
<property name="initialSize"> <!-- 连接池启动时的初始值 -->
<value>1</value>
</property>
<property name="maxActive"> <!-- 连接池的最大值,设置为0时,表示没有限制; -->
<value>255</value>
</property>
<!--最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
<property name="maxIdle">
<value>2</value>
</property>
<property name="minIdle"> <!--最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请为止 -->
<value>1</value>
</property>
<property name="maxWait"> <!--最大等待时间,超过时间会报出错误信息; -->
<value>120000</value>
</property>
</bean>
提供了close()方法关闭数据源,所以必须设定destroy-method=”close”属性, 以便Spring容器关闭时,数据源能够正常关闭。除以上必须的数据源属性外,还有一些常用的属性:
设置从数据源中返回的连接是否采用自动提交机制,默认值为true;
设置数据源是否仅能执行只读操作, 默认值为false;
最大连接数据库连接数,设置为0时,表示没有限制;
最大等待连接中的数量,设置为0时,表示没有限制;
最大等待秒数,单位为毫秒, 超过时间会报出错误信息;
用于验证连接是否成功的查询SQL语句,SQL语句必须至少要返回一行数据, 如你可以简单地设置为:“select count(*) from user”;
是否自我中断,默认是 false ;
几秒后数据连接会自动断开,在removeAbandoned为true,提供该值;
是否记录中断事件, 默认为 false
3、使用com.mchange.v2.c3p0.ComboPooledDataSource
说明:使用c3p0连接池,必须导入c3p0的jar包,在0.9.1版本之前,c3p0只有一二jar包:c3p0-0.9.1.jar,从0.9.2之后又分离出另外一个包:mchange-commons-java-0.2.11.jar,我这里使用的0.9.5.2的版本,所以我导入了两个jar包:c3p0-0.9.5.2.jar、mchange-commons-java-0.2.11.jar。
<bean id="dataSourceC3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
ComboPooledDataSource和BasicDataSource一样提供了一个用于关闭数据源的close()方法,这样我们就可以保证Spring容器关闭时数据源能够成功释放。
C3P0拥有比DBCP更丰富的配置属性,通过这些属性,可以对数据源进行各种有效的控制:
acquireIncrement:当连接池中的连接用完时,C3P0一次性创建新连接的数目;
acquireRetryAttempts:定义在从数据库获取新连接失败后重复尝试获取的次数,默认为30;
acquireRetryDelay:两次连接中间隔时间,单位毫秒,默认为1000;
autoCommitOnClose:连接关闭时默认将所有未提交的操作回滚。默认为false;
automaticTestTable: C3P0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数,那么属性preferredTestQuery将被忽略。 你 不能在这张Test表上进行任何操作,它将中为C3P0测试所用,默认为null;
breakAfterAcquireFailure: 获取连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认为false;
checkoutTimeout:当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒,默认为0;
connectionTesterClassName: 通过实现ConnectionTester或QueryConnectionTester的类来测试连接,类名需设置为全限定名。默认为com.mchange.v2.C3P0.impl.DefaultConnectionTester;
idleConnectionTestPeriod:隔多少秒检查所有连接池中的空闲连接,默认为0表示不检查;
initialPoolSize:初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值。默认为3;
maxIdleTime:最大空闲时间,超过空闲时间的连接将被丢弃。为0或负数则永不丢弃。默认为0;
maxPoolSize:连接池中保留的最大连接数。默认为15;
maxStatements: JDBC的标准参数,用以控制数据源内加载的PreparedStatement数量。但由于预缓存的Statement属 于单个Connection 而不是整个连接池。所以设置这个参数需要考虑到多方面的因素,如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。默认为0;
maxStatementsPerConnection:连接池内单个连接所拥有的最大缓存Statement数。默认为0;
numHelperThreads:C3P0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能,通过多线程实现多个操作同时被执行。默认为3;
preferredTestQuery:定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个参数能显著提高测试速度。测试的表必须在初始数据源的时候就存在。默认为null;
propertyCycle: 用户修改系统配置参数执行前最多等待的秒数。默认为300;
testConnectionOnCheckout: 因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都 将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable等方法来提升连接测试的性能。默认为false;
testConnectionOnCheckin:如果设为true那么在取得连接的同时将校验连接的有效性。默认为false。
4、使用org.logicalcobwebs.proxool.ProxoolDataSource
需导入proxool-0.9.1.jar、proxool-cglib.jar包可以读取.properties文件也可以配置proxool.xml文件,以下是读取.properties文件形式
<bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
<property name="driver" value="${proxool.driver}" />
<property name="driverUrl" value="${proxool.url}" />
<property name="user" value="${proxool.user}" />
<property name="password" value="${proxool.password}" />
<!-- 测试的SQL执行语句 -->
<property name="houseKeepingTestSql" value="${proxool.houseKeepingTestSql}" />
<!-- 最少保持的空闲连接数 (默认2个) -->
<property name="prototypeCount" value="${proxool.prototypeCount}" />
<!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒) -->
<property name="houseKeepingSleepTime" value="${proxool.hourseKeepingSleepTime}" />
<!-- 最大活动时间(超过此时间线程将被kill,默认为5分钟) -->
<property name="maximumActiveTime" value="${proxool.maximumActiveTime}" />
<!-- 连接最长时间(默认为4个小时) -->
<property name="maximumConnectionLifetime" value="${proxool.maximumConnectionLifetime}" />
<!-- 最大连接数 (默认5个) -->
<property name="maximumConnectionCount" value="${proxool.maximumConnectionCount}" />
<!-- 最小连接数 (默认2个) -->
<property name="minimumConnectionCount" value="${proxool.minimumConnectionCount}" />
<property name="simultaneousBuildThrottle" value="${proxool.simultaneous-build-throttle}" />
</bean>
<!--然后注入到sessionFactory中 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="proxoolDataSource" />
</bean>
db.properties配置文件
proxool.driver=oracle.jdbc.driver.OracleDriver
proxool.url=jdbc:oracle:thin:@localhost:1521:orcl
proxool.user=scott
proxool.password=wodemima
proxool.houseKeepingTestSql=select CURRENT_DATE
proxool.prototypeCount=3
proxool.hourseKeepingSleepTime=60000
proxool.maximumActiveTime=60000
proxool.maximumConnectionLifetime=18000000
proxool.minimumConnectionCount=3
proxool.maximumConnectionCount=50
proxool.simultaneous-build-throttle=10
proxool.recentlyStartedThreshold=60000
proxool.overloadWithoutRefusalLifetime=50000
配置说明:
alias -〉数据库连接别名(程序中需要使用的名称)
driver-url -〉数据库驱动
driver-class -〉驱动程序类
driver-properties -〉联机数据库的用户和密码
minimum-connection-count -〉最小连接数量,建议设置0以上,保证第一次连接时间
maximum-connection-count -〉最大连接数量,如果超过最大连接数量则会抛出异常。连接数设置过多,服务器CPU和内存性能消耗很大。
simultaneous-build-throttle -〉同时最大连接数
prototype-count -〉一次产生连接的数量。 例:如果现在prototype-count设置为4个,但是现在已经有2个可以获得的连接,那么将会试图再创建2个连接。但不能超过最大连接数。
maximum-active-time -〉连接最大时间活动 默认5分钟
maximum-connection-lifetime -〉连接最大生命时间 默认4小时
C3P0比较耗费资源,效率方面可能要低一点。
DBCP在实践中存在BUG,在某些种情会产生很多空连接不能释放,Hibernate3.0已经放弃了对其的支持。
Proxool的负面评价较少,现在比较推荐它
5、使用org.springframework.jndi.JndiObjectFactoryBean
说明:JndiObjectFactoryBean 能够通过JNDI获取DataSource,需要在web server中配置数据源,不方便于部署
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>Java:comp/env/jdbc/roseindiaDB_local</value>
</property>
</bean>
如果应用配置在高性能的应用服务器(如WebLogic或Websphere等)上,我们可能更希望使用应用服务器本身提供的数据源。应用服务器的数据源 使用JNDI开放调用者使用,Spring为此专门提供引用JNDI资源的JndiObjectFactoryBean类。
6、使用org.springframework.orm.hibernate3.LocalSessionFactoryBean
这是hibernate数据源连接池,需要hiberante核心jar包,数据库连接方式写在hiberante的配置文件中,在spring管理hibernate中的配置文件中,直接读取hibernate核心配置文件即可。在使用hibernate连接数据库的时候需要读取hibernate.cfg.xml的配置文件和相应的实类,读者可参照下面的自己配置一下
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocations">
<list>
<value>classpath:com/config/hibernate.cfg.xml</value>
</list>
</property>
<property name="mappingLocations">
<!-- 所有的实体类映射文件 -->
<list>
<value>classpath:com/hibernate/*.hbm.xml</value>
</list>
</property>
</bean>
以上1、2、3、4前面要加
<!-- 读取数据源文件 -->
<context:property-placeholder location="classpath:db.properties" />
来加载读取配置文件