spring配置多数据源

    xiaoxiao2021-03-25  56

    基于spring来配置和使用多数据源还是比较简单的,因为spring框架已经预留了这样的接口可以方便数据源的切换。

    DynamicDataSource类

    package com.demo.core; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { // 从自定义的位置获取数据源标识 return DynamicDataSourceHolder.getDataSource(); } }DynamicDataSourceHolder类

    package com.demo.core; public class DynamicDataSourceHolder { /** * 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰 */ private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>(); public static String getDataSource() { return THREAD_DATA_SOURCE.get(); } public static void setDataSource(String dataSource) { THREAD_DATA_SOURCE.set(dataSource); } public static void clearDataSource() { THREAD_DATA_SOURCE.remove(); } }

    注解

    package com.demo.core; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ ElementType.TYPE,ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface DataSource { String value(); }切面

    package com.demo.core; import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; public class DataSourceAspect { /** * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源 * * @param point * @throws Exception */ public void intercept(JoinPoint point) throws Exception { Class<?> target = point.getTarget().getClass(); MethodSignature signature = (MethodSignature) point.getSignature(); // 默认使用目标类型的注解,如果没有则使用其实现接口的注解 for (Class<?> clazz : target.getInterfaces()) { resolveDataSource(clazz, signature.getMethod()); } resolveDataSource(target, signature.getMethod()); } /** * 提取目标对象方法注解和类型注解中的数据源标识 * * @param clazz * @param method */ private void resolveDataSource(Class<?> clazz, Method method) { try { Class<?>[] types = method.getParameterTypes(); // 默认使用类型注解 if (clazz.isAnnotationPresent(DataSource.class)) { DataSource source = clazz.getAnnotation(DataSource.class); DynamicDataSourceHolder.setDataSource(source.value()); } // 方法注解可以覆盖类型注解 Method m = clazz.getMethod(method.getName(), types); if (m != null && m.isAnnotationPresent(DataSource.class)) { DataSource source = m.getAnnotation(DataSource.class); DynamicDataSourceHolder.setDataSource(source.value()); } } catch (Exception e) { System.out.println(clazz + ":" + e.getMessage()); } } }service类

    package com.demo.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import com.demo.core.DataSource; import com.demo.core.DynamicDataSourceHolder; import com.demo.dao.UserDAO; import com.demo.model.User; import com.demo.service.UserService; @Service public class UserServiceImpl implements UserService{ @Autowired @Qualifier("userDAO") private UserDAO userDAO; public int insertUser(User user) { return userDAO.insertUser(user); } public User queryUserById(String id) { return userDAO.queryUserByID(id); } @DataSource("dataSource1")//通过元注解 利用切面运行时自动设置数据源 public User queryUserByIdDB2(String id) { //DynamicDataSourceHolder.setDataSource("dataSource2"); //手动设置数据源 return userDAO.queryUserByID(id); } }dao类

    package com.demo.dao; import org.springframework.stereotype.Repository; import com.demo.model.User; @Repository public interface UserDAO { public int insertUser(User user); public User queryUserByID(String id); }

    单元测试service

    package test.service; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.demo.service.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"/conf/spring-mybatis.xml"}) //加载配置文件 public class userServiceTest{ @Autowired private UserService userservice; @Test public void testuserService(){ // System.err.println(userservice.queryUserById("1")); System.err.println(userservice.queryUserByIdDB2("1")); } }控制台输出 User [id=1, name=数据源1, password=admin1]

    User [id=1, name=数据源2, password=admin2]

    配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- 引入jdbc配置文件 --> <context:property-placeholder location="classpath:conf/jdbc.properties"/> <context:component-scan base-package="com.demo"/> <!-- mybatis文件配置,扫描所有mapper文件 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dynamicDataSource" p:configLocation="classpath:conf/mybatis-config.xml" p:mapperLocations="classpath:mapper/*.xml" /> <!-- configLocation为mybatis属性 mapperLocations为所有mapper --> <!-- spring与mybatis整合配置,扫描所有dao ,生成与DAO类相同名字的bean(除了首字母小写)--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="com.demo.dao" p:sqlSessionFactoryBeanName="sqlSessionFactory" /> <!-- 对数据源进行事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dynamicDataSource" /> <tx:annotation-driven mode="proxy" transaction-manager="transactionManager" /> <!--创建数据源dataSource--> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="${jdbc_driverClassName}" /> <property name="url" value="${jdbc_url}" /> <property name="username" value="${jdbc_username}" /> <property name="password" value="${jdbc_password}" /> </bean> <!--创建数据源dataSource2 --> <bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${db2.driver}" /> <property name="url" value="${db2.url}" /> <property name="username" value="${db2.username}" /> <property name="password" value="${db2.password}" /> </bean> <bean id="dynamicDataSource" class="com.demo.core.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <!-- 指定lookupKey和与之对应的数据源 --> <entry key="dataSource" value-ref="dataSource"></entry> <entry key="dataSource2" value-ref="dataSource2"></entry> </map> </property> <!-- 这里可以指定默认的数据源 --> <property name="defaultTargetDataSource" ref="dataSource" /> </bean> <bean id="dataSourceAspect" class="com.demo.core.DataSourceAspect"></bean> <!-- 自定义注解 AOP切换数据源 --> <aop:config> <aop:aspect id="concurrentOperationRetry" ref="dataSourceAspect"> <!-- 拦截所有service方法 * com.service.imp.*.*(..)--> <aop:pointcut id="dataSourcePointcut" expression="execution(* com.demo.service.*.*(..))"/> <aop:before pointcut-ref="dataSourcePointcut" method="intercept" /> </aop:aspect> </aop:config> </beans> 转载 http://www.cnblogs.com/liujiduo/p/5004691.html  基于注解的Spring多数据源配置和使用 推荐

    转载 http://blog.csdn.net/wangpeng047/article/details/8866239/ spring多数据源配置

    转载 http://download.csdn.net/download/npf_java/8786825 多数据源事务控制

    转载请注明原文地址: https://ju.6miu.com/read-40028.html

    最新回复(0)