16
Datasource
Calvin Xiao edited this page 2014-02-08 01:19:05 -08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

1. Tomcat JDBC

DBCP作为老牌DataSource一统江湖很久也很久没有更新了。但Tomcat JDBC 最近出来把它替换掉了,理由详见Tomcat JDBC的自述,简单来说你又慢,又复杂。 所幸Tomcat JDBC完全兼容DBCP的旧属性只要把spring配置文件里的class 名改掉就可以继续用了。

	<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
			<!-- Connection Info -->
			<property name="driverClassName" value="${jdbc.driver}" />
			<property name="url" value="${jdbc.url}" />
			<property name="username" value="${jdbc.username}" />
			<property name="password" value="${jdbc.password}" />
		
			<!-- Connection Pooling Info -->
			<property name="maxActive" value="${jdbc.pool.maxActive}" />
			<property name="maxIdle" value="${jdbc.pool.maxIdle}" />
			<property name="minIdle" value="0" />
			<property name="defaultAutoCommit" value="false" />
		</bean>

defaultAutoCommit=false好像是必须设置的否则事务好像会不灵光。maxActive和maxIdle的默认值是100可按需设置。minIdle的默认值是10建议设为0以免浪费。

maxWait(默认30秒)如果池里已没有连接可用会尝试等待一下等到30秒才抛错。

Idle连接的处理方式

  1. 当大于maxIdle后连接return到池时会被直接释放。
  2. 清理线程每隔timeBetweenEvictionRunsMillis运行一次(默认5秒如果设置为<0时则清理线程不运行):
    a.如果当前idle连接数 > minIdle数检查每个idle连接如果它的idle时间超过minEvictableIdleTimeMillis(默认60秒)则释放
    b.如果设置了testOnIdle=true(默认为false)以及validationQuery(如select 1 for mysql/h2/postsql, select 1 from dual for Oracle)则会对每个idle连接执行validate语句进行校验。

因为MySQL也会在服务端将idle过久的连接断掉所以如果使用MySQL要在连接池端处理好idle连接。这里与DBCP略有不同如果还想按minEvictableIdleTimeMillis回收必须将minIdle值设为0让它每次都对所有连接进行idle时间校验。另外timeBetweenEvictionRunsMillis和minEvictableIdleTimeMillis的值也可以适当调整。另外DBCP中的numTestsPerEvictionRun属性已失效会对全部连接进行测试。

为了防止应用忘记把连接还到连接池可以设置removeAbandoned(默认为false)借出连接超过removeAbandonedTimeout(默认60秒)的连接就会被干掉,也是在前面的清理线程中进行检查。

还有Tomcat JDBC的新feature可供进一步阅读。

bean定义里的destroy-method="close"也很重要。

另外温少的Druid连接池也是一个选择。

2. Spring Simple DataSource

在某些场合简简单单不想使用连接池也不想引入依赖包可以直接使用Spring自带的DataSource--SimpleDriverDataSource(替代了以前的与OSGI的ClassLoader不兼容的DriverManagerDataSource。)

	<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>

3. Log4jdbc显示SQL

想看实际产生的SQL最简单的方法是在applicationContext.xml的entityManagerFactory的配置中增加

<prop key="hibernate.show_sql">true</prop>

但hibernate自己的showsql看不到绑定的参数。如果要想看到实际执行的sql和实际绑定的参数可以使用log4jdbc。 log4jdbc一共有三个分支log4jdbc是原版最近终于加入Maven的主仓库中fork之一是log4jdbc-remix后来又再fork了一个log4jdbc-log4j2,最后还是选择用原版。

支持SQL打印的步骤如下

  1. 打开application.properties,换掉原来的jdbcdriver同时在原来的jdbc url的中间加上"log4jdbc",如
jdbc.driver=net.sf.log4jdbc.DriverSpy
jdbc.url=jdbc:log4jdbc:h2:file:~/.h2/quickstart;AUTO_SERVER=TRUE

2.设置Logger需要设置jdbc.sqltiming=INFO连SQL带执行时间打印出来如果只想看sql是jdbc.sqlonly=INFO在logback.xml里如下

<logger name="jdbc.sqltiming" level="INFO"/>

3.(可选)参照log4jdbc的文档在log4jdbc.properties文件中配置参数。\

  • log4jdbc.debug.stack.prefix只显示含调用栈的包名的语句。
  • log4jdbc.sqltiming.warn.threshold执行时间阀值单位为ms将Log级别调为Warning则只会打印执行较慢的语句。
  • log4jdbc.dump.sql.select/insert/update/delete 过滤掉某些类型的语句。