环境:Spring 3.0 ,Hibernate 3.5 ,同类型数据库(DB2)
编前语:此片仅粗略的描述使用Spring和Hibernate采用注入方式管理多数据源在不同事务的情况下使用的方法。
涉及到的文件三个:testDaoImpl (数据库操作文件),applicationContext.xml(Spring主配置文件) ,jdbc.properties (数据库连接和各种数据库相关配置文件)
总体分三步:
3.在需要使用不同数据源的操作实现类中指定新的sessionFactory和transactional
具体使用修改如下(注意:所有配置仅用于多数据源连接测试,并非优化后配置,套用需谨慎!):
1.增加数据库连接配置(该配置文件中包含了cpool的配置和hibernate的配置信息在xml配置中直接调用) jdbc.properties
jdbcq.driverClassName=com.db2.jcc.DB2Driver jdbcq.url=jdbc:db2://192.168.1.11:50001/DB01:currentSchema=USER1; jdbcq.username=user1 jdbcq.password=user1
2.在Spring配置中增加新的数据源配置 applicationContext.xml
(前提配置)
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:jdbc.properties</value> </property> </bean>
新增数据源:
<bean id="dataSourceQ" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbcq.driverClassName}" /> <property name="jdbcUrl" value="${jdbcq.url}" /> <property name="user" value="${jdbcq.username}" /> <property name="password" value="${jdbcq.password}" /> <property name="autoCommitOnClose" value="true" /> <property name="checkoutTimeout" value="${cpool.checkoutTimeout}" /> <property name="initialPoolSize" value="${cpool.minPoolSize}" /> <property name="minPoolSize" value="${cpool.minPoolSize}" /> <property name="maxPoolSize" value="${cpool.maxPoolSize}" /> <property name="maxIdleTime" value="${cpool.maxIdleTime}" /> <property name="acquireIncrement" value="${cpool.acquireIncrement}" /> <property name="acquireRetryAttempts" value="30" /> <property name="acquireRetryDelay" value="1000" /> <property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}" /> </bean>
sessionFactory配置:
此处实体包是注解方式必须有的,只有在sessionFactory 中进行扫描过的实体包才能在注入该sessionFactory的数据库操作impl中操作。否则会出现找不到对应实体的异常。此处仅扫描用于测试的包。
另外一点需要注意的是如果配置二级缓存那么需要使用不同的配置文件和配置,否则会出现缓存空间已经被使用的异常。当然用于测试可以直接去掉这部分配置
此处新建了另外一个配置文件,同时配置了不同的缓存空间
<!-- 新的sessioinFactory--> <bean id="sessionFactoryQ" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <!-- 新的数据源--> <property name="dataSource" ref="dataSourceQ" /> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop> <prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop> <!-- 使用ehcache --> <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> <!-- 最优化二级缓存 --> <prop key="hibernate.cache.use_structured_entries">true</prop> <prop key="hibernate.cache.provider_configuration_file_resource_path">/ehcache-hibernate-q.xml</prop> </props> </property> <!-- 扫描实体所在包 只扫描业务包--> <property name="packagesToScan" > <list> <value>com.back.entities.test</value> </list> </property> </bean>
事务管理配置:
<!-- 指定事务管理 --> <bean id="transactionManagerQ" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactoryQ" /> </bean> <!-- 使用annotation定义事务 --> <tx:annotation-driven transaction-manager="transactionManagerQ" />
3.在需要使用不同数据源的操作实现类中指定新的sessionFactory和transactional
@Repository @Transactional("transactionManagerQ") public class TestDaoImpl implements TestDao { private SessionFactory sessionFactory; @Resource(name="sessionFactoryQ") public void setSessionFactory(SessionFactory sessionFactoryQ) { this.sessionFactory = sessionFactoryQ; } }
大概就是这样,需要配置和修改的地方都如上已经处理了。因为是注解所以和纯xml配置会有不同的地方。数据库操作的实现类在项目中其实会继承框架的一个实现类,但为了便于看到全貌,所以修改成以上的样子,从而可以看到sessionFactory的设置。