Spring配置多個(gè)數(shù)據(jù)源并實(shí)現(xiàn)數(shù)據(jù)源的動(dòng)態(tài)切換功能
1.首先在config.properties文件中配置兩個(gè)數(shù)據(jù)庫連接的基本數(shù)據(jù)。這個(gè)省略了
2.在spring配置文件中配置這兩個(gè)數(shù)據(jù)源:
數(shù)據(jù)源1
<!-- initialSize初始化時(shí)建立物理連接的個(gè)數(shù)0 maxActive最大連接池?cái)?shù)量8 minIdle最小連接池?cái)?shù)量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>
數(shù)據(jù)源2
<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.自定義一個(gè)數(shù)據(jù)源類,該類繼承 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
并重寫determineCurrentLookupKey()方法
3.1代碼如下
public class RoutingDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceHolder.getDataSourceType(); } }
3.2將該類交由sping管理,其在spring配置文件中配置如下
<bean id="dataSource" class="com.coe.exp.core.dataSource.RoutingDataSource"> <!-- 為targetDataSources注入兩個(gè)數(shù)據(jù)源 --> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="ds1" value-ref="dataSource1"/> <entry key="ds2" value-ref="dataSource2"/> </map> </property> <!-- 為指定數(shù)據(jù)源RoutingDataSource注入默認(rèn)的數(shù)據(jù)源--> <property name="defaultTargetDataSource" ref="dataSource1"/> </bean>
3.3spring其他的配置如下
<!-- 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> <!-- 配置事務(wù)管理器 --> <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" /> <!-- 自動(dòng)掃描(自動(dòng)注入) --> <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"/> <!-- 自動(dòng)掃描定時(shí)任務(wù) --> <task:annotation-driven/> <!-- spring自動(dòng)創(chuàng)建代理,植入切面,proxy-target-class屬性,默認(rèn)為false,表示使用jdk動(dòng)態(tài)代理織入增強(qiáng),當(dāng)配為<aop:aspectj-autoproxy poxy-target-class="true"/>時(shí),表示使用CGLib動(dòng)態(tài)代理技術(shù)織入增強(qiáng)。不過即使proxy-target-class設(shè)置為false,如果目標(biāo)類沒有聲明接口,則spring將自動(dòng)使用CGLib動(dòng)態(tài)代理。 --> <aop:aspectj-autoproxy proxy-target-class="true"/> <import resource="../shiro/spring-shiro.xml"/>
4.編寫一個(gè)數(shù)據(jù)源持有類DataSourceHolder
public class DataSourceHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); /** * @Description: 設(shè)置數(shù)據(jù)源類型 * @param dataSourceType 數(shù)據(jù)庫類型 * @return void * @throws */ public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } /** * @Description: 獲取數(shù)據(jù)源類型 * @param * @return String * @throws */ public static String getDataSourceType() { return contextHolder.get(); } /** * @Description: 清除數(shù)據(jù)源類型 * @param * @return void * @throws */ public static void clearDataSourceType() { contextHolder.remove(); } }
5.自定義注解
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; /** * 數(shù)據(jù)源 * * @author llb 2017-03-30 * */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Component public @interface DataSource { String value() default ""; }
6.動(dòng)態(tài)切換數(shù)據(jù)源
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數(shù)據(jù)源持有類 DataSourceHolder.setDataSourceType(datasource.value()); } } }
7.若方法體上沒有注解,則都是使用默認(rèn)數(shù)據(jù)源,如果有以下注解,則使用指定的數(shù)據(jù)源
/** * 查詢哲盟數(shù)據(jù)庫中所有狀態(tài)正常的客戶余額 * @return * @author mxl * @version 2017年8月16日下午1:30:06 */ @DataSource("ds2") public List<CustomerBalanceEnt> getAllCustBalanceByZm(){ return customerBalanceMapper.getAllCustBalanceByZm(); }
上面這個(gè)方法就是使用“ds2”;
到此這篇關(guān)于Spring配置多個(gè)數(shù)據(jù)源并實(shí)現(xiàn)數(shù)據(jù)源的動(dòng)態(tài)切換的文章就介紹到這了,更多相關(guān)Spring配置多個(gè)數(shù)據(jù)源內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot集成@DS注解實(shí)現(xiàn)數(shù)據(jù)源切換的方法示例
- springboot+dynamicDataSource動(dòng)態(tài)添加切換數(shù)據(jù)源方式
- SpringBoot?+DynamicDataSource切換多數(shù)據(jù)源的全過程
- Springboot實(shí)現(xiàn)根據(jù)用戶ID切換動(dòng)態(tài)數(shù)據(jù)源
- Springboot動(dòng)態(tài)切換數(shù)據(jù)源的具體實(shí)現(xiàn)與原理分析
- 詳細(xì)聊聊SpringBoot中動(dòng)態(tài)切換數(shù)據(jù)源的方法
- Spring配置多數(shù)據(jù)源切換
- SpringBoot AOP方式實(shí)現(xiàn)多數(shù)據(jù)源切換的方法
相關(guān)文章
Java為什么匿名內(nèi)部類參數(shù)引用需要用final進(jìn)行修飾?
今天小編就為大家分享一篇關(guān)于Java為什么匿名內(nèi)部類參數(shù)引用需要用final進(jìn)行修飾?,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-04-04Java基于NIO實(shí)現(xiàn)群聊系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java基于NIO實(shí)現(xiàn)群聊系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11JDK基于CAS實(shí)現(xiàn)原子類盤點(diǎn)解析
這篇文章主要為大家介紹了JDK基于CAS實(shí)現(xiàn)原子類盤點(diǎn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Java同步框架AbstractQueuedSynchronizer詳解
本篇文章主要介紹了Java同步框架AbstractQueuedSynchronizer詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10