spring + mybatis配置及网络异常设置

Spring引入mybatis

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd ">
 
    <context:component-scan base-package="com.bf.health" />
    
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@192.168.0.69:1521:orcl"/>
        <property name="username" value="BFDEVDB_301"/>
        <property name="password" value="bfdevdb"/>
    </bean>
          
    <!-- 创建SqlSessionFactory,同时指定数据源-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <property name="basePackage" value="com.bf.health.dao" /> </bean> </beans>

要加上事务控制,则在</beans>前加上

<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">     
    <property name="dataSource" ref="dataSource"></property>
</bean>     
  
<tx:annotation-driven transaction-manager="transactionManager" />

 由于我们用的mybatis3的注解,因此spring的sqlSessionTemplate也不用配置了,sqlSessionTemplate也不用注入到我们的BaseDAO中了。

另外发现<property name="basePackage" value="com.bf.health.dao" />也可以不配置。

最后呈上完整xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
 
    <context:component-scan base-package="com.bf.health" />
    
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@192.168.101.21:1521:orcl"/>
        <property name="username" value="BF_HEALTH_01"/>
        <property name="password" value="winway_health_20161013"/>
    </bean>
          
    <!-- 创建SqlSessionFactory,同时指定数据源-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
           <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.bf.health.dao" />
    </bean>
    
    <!-- ================================事务相关控制===================================================== -->
      <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">     
          <property name="dataSource" ref="dataSource"></property>
    </bean>     
  
    <tx:annotation-driven transaction-manager="transactionManager" />
 </beans>

 实际项目中发现当网络断开又重新连接上之后,系统连接数据库异常,原因应该是当前线程池中的连接实际上已经失效了,但dbcp仍认为它是有效的,因此仍在尝试用旧连接访问数据库,直至网络超时。

可参见:dbcp重连问题排查

需修改配置如下:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@192.168.101.21:1521:orcl"/>
        <property name="username" value="BF_HEALTH_01"/>
        <property name="password" value="winway_health_20161013"/>      
        <property name="testWhileIdle"><value>true</value></property> <!-- 打开检查,用异步线程evict进行检查 -->  
        <property name="testOnBorrow"><value>false</value></property>  
        <property name="testOnReturn"><value>false</value></property>  
        <property name="validationQuery"><value>select sysdate from dual</value></property>  
        <property name="validationQueryTimeout"><value>1</value></property>  
        <property name="timeBetweenEvictionRunsMillis"><value>30000</value></property>  
        <property name="numTestsPerEvictionRun"><value>20</value></property>  
    </bean>

具体解释,参照dbcp基本配置和重连配置

 dbcp的链接validate配置
  1. dbcp是采用了commons-pool做为其连接池管理,testOnBorrow,testOnReturn, testWhileIdle是pool是提供的几种校验机制,通过外部钩子的方式回调dbcp的相关数据库链接(validationQuery)校验
  2. dbcp相关外部钩子类:PoolableConnectionFactory,继承于common-pool PoolableObjectFactory
  3. dbcp通过GenericObjectPool这一入口,进行连接池的borrow,return处理
  4. testOnBorrow : 顾明思义,就是在进行borrowObject进行处理时,对拿到的connection进行validateObject校验
  5. testOnReturn : 顾明思义,就是在进行returnObject对返回的connection进行validateObject校验,个人觉得对数据库连接池的管理意义不大
  6. testWhileIdle : 关注的重点,GenericObjectPool中针对pool管理,起了一个Evict的TimerTask定时线程进行控制(可通过设置参数timeBetweenEvictionRunsMillis>0),定时对线程池中的链接进行validateObject校验,对无效的链接进行关闭后,会调用ensureMinIdle,适当建立链接保证最小的minIdle连接数。
  7. timeBetweenEvictionRunsMillis,设置的Evict线程的时间,单位ms,大于0才会开启evict检查线程
  8. validateQuery, 代表检查的sql
  9. validateQueryTimeout, 代表在执行检查时,通过statement设置,statement.setQueryTimeout(validationQueryTimeout)
  10. numTestsPerEvictionRun,代表每次检查链接的数量,建议设置和maxActive一样大,这样每次可以有效检查所有的链接.


签名:删除冗余的代码最开心,找不到删除的代码最痛苦!
原文地址:https://www.cnblogs.com/season2009/p/6179427.html