您的位置:首页 > 大数据 > 人工智能

Mybaits多数据源配置

2016-06-07 13:17 309 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/juvconan/article/details/51603014

最近搞一个项目需要用spring + mybatis连接两个数据源,上网查了一些资料,整理了一下,共有两种办法实现。


一、配置两个sessionFactory

<!-- 配置哪些类的方法需要进行事务管理 --><aop:config><aop:pointcut id="allManagerMethod1" expression="execution(* com.xyzq.ylb.services..*.*(..))" /><aop:advisor advice-ref="txAdvice1" pointcut-ref="allManagerMethod1" /></aop:config><!-- 这里使用Spring自带的DriverManagerDataSource,实际开发产品应该使用具有连接持管理的DataSource等 --><tx:advice id="txAdvice1" transaction-manager="txManager1"><tx:attributes><tx:method name="query*" read-only="true" propagation="NOT_SUPPORTED"/><tx:method name="get*"  read-only="true" propagation="NOT_SUPPORTED"/><tx:method name= "*" propagation="REQUIRED"/></tx:attributes></tx:advice><bean id="txManager1"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource1" /></bean><bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource1" /><property name="typeAliasesPackage" value="com.xyzq.ylb.domain;com.xyzq.platform.domain" /><property name="typeHandlersPackage" value="com.xyzq.platform.dao.handle"></property><property name="mapperLocations" value="classpath*:com/xyzq/ylb/dao/local/*Dao.xml"></property></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.xyzq.ylb.dao.local;com.xyzq.platform.dao;" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1"/></bean><tx:advice id="txAdvice2" transaction-manager="txManager2"><tx:attributes><tx:method name= "*" read-only="true" propagation="NOT_SUPPORTED"/></tx:attributes></tx:advice><aop:config><aop:pointcut id="allManagerMethod2"expression="execution(* com.xyzq.ylb.services..*.*(..))" /><aop:advisor advice-ref="txAdvice2" pointcut-ref="allManagerMethod2" /></aop:config><bean id="txManager2"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource2" /></bean><bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource2" /><property name="typeAliasesPackage" value="com.xyzq.ylb.domain;com.xyzq.platform.domain" /><property name="typeHandlersPackage" value="com.xyzq.platform.dao.handle"></property><property name="mapperLocations" value="classpath*:com/xyzq/ylb/dao/remote/*Dao.xml"></property></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.xyzq.ylb.dao.remote;" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"/></bean>
<pre name="code" class="html">dataSource根据你选择的数据源进行配置,这里就不贴了。我的mybatis使用自动扫描注入,这种配置方式的要点在于每个SqlSessionFactoryBean都要指定不同的<mapperLocations,即不同包路径下的Mapper对应不同的数据源
<property name="mapperLocations" value="classpath*:com/xyzq/ylb/dao/remote/*Dao.xml"></property>
<pre name="code" class="html"><pre name="code" class="html">同时要为不同的MapperScannerConfigurer显示指定basePackage和sqlSessionFactoryBeanName
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.xyzq.ylb.dao.local;com.xyzq.platform.dao;" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1"/></bean>

二、在网络上看了一些利用Spring aop来做动态切换数据源  ,也尝试了一下,首先新建两个类MultipleDataSource和DataSourceInterceptor

MultipleDataSource

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class MultipleDataSource extends AbstractRoutingDataSource {private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();public static void setDataSourceKey(String dataSource) {dataSourceKey.set(dataSource);}@Overrideprotected Object determineCurrentLookupKey() {Object o = dataSourceKey.get();return o;}}
DataSourceInterceptor

import org.aspectj.lang.JoinPoint;import org.springframework.stereotype.Component;@Componentpublic class DataSourceInterceptor {public void setDataSourceOne(JoinPoint jp) {MultipleDataSource.setDataSourceKey("dataSource1");}public void setDataSourceTwo(JoinPoint jp) {MultipleDataSource.setDataSourceKey("dataSource2");}}

Spring.xml中的关键配置如下

      <bean id="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="multipleDataSource"  /></bean><!--  这里使用Spring自带的DriverManagerDataSource,实际开发产品应该使用具有连接持管理的DataSource等--><tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="query*" read-only="true" propagation="NOT_SUPPORTED"/><tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/><tx:method name="*" propagation="REQUIRED"/></tx:attributes></tx:advice><aop:config><aop:pointcut id="allManagerMethod" expression="execution(* com.xyzq.ylb.services..*.*(..))" /><aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" order="1"/></aop:config><!-- 数据连接源配置 --><aop:config><aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor" order="0"><aop:pointcut id="daoOne" expression="execution(* com.xyzq.ylb.services.local.*.*(..))" /><aop:pointcut id="daoTwo" expression="execution(* com.xyzq.ylb.services.remote.*.*(..))" /><aop:before pointcut-ref="daoOne" method="setDataSourceOne" /><aop:before pointcut-ref="daoTwo" method="setDataSourceTwo" /></aop:aspect></aop:config><bean id="multipleDataSource" class="com.xyzq.ylb.datasouce.MultipleDataSource"><property name="defaultTargetDataSource" ref="dataSource1"/><property name="targetDataSources"><map><entry key="dataSource1" value-ref="dataSource1"/><entry key="dataSource2" value-ref="dataSource2"/></map></property></bean><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="multipleDataSource" /><property name="typeAliasesPackage" value="com.xyzq.ylb.domain;com.xyzq.platform.domain" /><property name="typeHandlersPackage" value="com.xyzq.platform.dao.handle"></property><property name="mapperLocations" value="classpath*:com/xyzq/ylb/dao/**/*Dao.xml"></property></bean><!-- mybatis.spring自动映射 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.xyzq.ylb.dao"/><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/></bean>


原理百度搜索mybatis多数据源,基本都是这个方式。这个配置我一开始做的时候总是失败,后面发现是因为我在这里的数据库操作使用了事务,在起事务的时候已经选择了数据源,后面的aop:aspect 就没用了,所以要给aop:advisor和aop:aspect加上order属性,确保选择数据源的织入在事务之前。

三、不完善的地方

这个多数据源配置只能实现不用的方法或不同包路径下的类使用不同数据源,并没有使用分布式事务,这个后面再研究一下。










内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: