Spring配置多个数据源并实现数据源的动态切换功能
1.首先在config.properties文件中配置两个数据库连接的基本数据。这个省略了
2.在spring配置文件中配置这两个数据源:
数据源1
1 2 3 4 5 6 7 8 9 | <!-- initialSize初始化时建立物理连接的个数0 maxActive最大连接池数量8 minIdle最小连接池数量0--> <bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource" scope="singleton"> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="url" value="${jdbc.url}" /> <property name="initialSize" value="${jdbc.init}" /> <property name="maxActive" value="${jdbc.max}" /> <property name="minIdle" value="${jdbc.min}" /> </bean> |
数据源2
1 2 3 4 5 6 7 8 | <bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource" scope="singleton"> <property name="username" value="${jdbc.username2}" /> <property name="password" value="${jdbc.password2}" /> <property name="url" value="${jdbc.url2}" /> <property name="initialSize" value="${jdbc.init2}" /> <property name="maxActive" value="${jdbc.max2}" /> <property name="minIdle" value="${jdbc.min2}" /> </bean> |
3.自定义一个数据源类,该类继承 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
并重写determineCurrentLookupKey()方法
3.1代码如下
1 2 3 4 5 6 | public class RoutingDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceHolder.getDataSourceType(); } } |
3.2将该类交由sping管理,其在spring配置文件中配置如下
1 2 3 4 5 6 7 8 9 10 11 | <bean id="dataSource" class="com.coe.exp.core.dataSource.RoutingDataSource"> <!-- 为targetDataSources注入两个数据源 --> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="ds1" value-ref="dataSource1"/> <entry key="ds2" value-ref="dataSource2"/> </map> </property> <!-- 为指定数据源RoutingDataSource注入默认的数据源--> <property name="defaultTargetDataSource" ref="dataSource1"/> </bean> |
3.3spring其他的配置如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <!-- MyBatis配置 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 把dataSource注入给sqlSessionFactory --> <property name="dataSource" ref="dataSource" /> <property name="typeAliasesPackage" value="com.coe.exp.core.ent" /> <!-- 指定mapper.xml的位置 --> <property name="mapperLocations" > <array> <value>classpath:com/coe/exp/core/xml/**/*.xml</value> <value>classpath:com/coe/exp/xml/**/*.xml</value> </array> </property> <!-- 指定myBatis配置文件的位置 --> <property name="configLocation" value="classpath:mybatis/sqlmapconfig.xml" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.coe.exp.core.mapper,com.coe.exp.mapper" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="remove*" propagation="REQUIRED"/> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="find*" propagation="SUPPORTS"/> <tx:method name="get*" propagation="SUPPORTS"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.coe.exp.dao..*Impl.*(..))" order="2"/> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.coe.exp.core.dao..*Impl.*(..))" order="3"/> </aop:config> <!-- 注解方式配置事物 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 引入属性文件 --> <context:property-placeholder location="classpath:config.properties" /> <!-- 自动扫描(自动注入) --> <context:component-scan base-package="com.coe.exp,mm" annotation-config="true"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <context:component-scan base-package="com.coe,mm"/> <!-- 自动扫描定时任务 --> <task:annotation-driven/> <!-- spring自动创建代理,植入切面,proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy poxy-target-class="true"/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。 --> <aop:aspectj-autoproxy proxy-target-class="true"/> <import resource="../shiro/spring-shiro.xml"/> |
4.编写一个数据源持有类DataSourceHolder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class DataSourceHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); /** * @Description: 设置数据源类型 * @param dataSourceType 数据库类型 * @return void * @throws */ public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } /** * @Description: 获取数据源类型 * @param * @return String * @throws */ public static String getDataSourceType() { return contextHolder.get(); } /** * @Description: 清除数据源类型 * @param * @return void * @throws */ public static void clearDataSourceType() { contextHolder.remove(); } } |
5.自定义注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.stereotype.Component; /** * 数据源 * * @author llb 2017-03-30 * */ @Target (ElementType.METHOD) @Retention (RetentionPolicy.RUNTIME) @Component public @interface DataSource { String value() default "" ; } |
6.动态切换数据源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Repository; import com.coe.exp.core.dataSource.DataSourceHolder; @Order ( 1 ) @Aspect @Repository public class DataSourceAspect { @Pointcut ( "execution(* com..dao..*Impl.*(..))" ) private void anyMethod() { } @AfterReturning (value = "anyMethod()" , returning = "result" ) public void afterReturning(JoinPoint joinPoint,Object result){ DataSourceHolder.clearDataSourceType(); } @Before (value= "anyMethod()" ) public void before(JoinPoint joinPoint) throws Throwable { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Method method = methodSignature.getMethod(); //如果方法体上使用了DataSource注解 if (method.isAnnotationPresent(DataSource. class )) { //获取该方法上的注解名 DataSource datasource = method.getAnnotation(DataSource. class ); //将方法体上的注解的值赋予给DataSourceHolder数据源持有类 DataSourceHolder.setDataSourceType(datasource.value()); } } } |
7.若方法体上没有注解,则都是使用默认数据源,如果有以下注解,则使用指定的数据源
1 2 3 4 5 6 7 8 9 10 | /** * 查询哲盟数据库中所有状态正常的客户余额 * @return * @author mxl * @version 2017年8月16日下午1:30:06 */ @DataSource ( "ds2" ) public List<CustomerBalanceEnt> getAllCustBalanceByZm(){ return customerBalanceMapper.getAllCustBalanceByZm(); } |
上面这个方法就是使用“ds2”;
到此这篇关于Spring配置多个数据源并实现数据源的动态切换的文章就介绍到这了,更多相关Spring配置多个数据源内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
Spring处理@Async导致的循环依赖失败问题的方案详解
这篇文章主要为大家详细介绍了SpringBoot中的@Async导致循环依赖失败的原因及其解决方案,文中的示例代码讲解详细,感兴趣的可以学习一下2022-07-07StringUtils工具包中字符串非空判断isNotEmpty和isNotBlank的区别
今天小编就为大家分享一篇关于StringUtils工具包中字符串非空判断isNotEmpty和isNotBlank的区别,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧2018-12-12
最新评论