本项目是基于其他博主(https://www.cnblogs.com/lzrabbit/p/3750803.html)做了加工,
配置类 前三个是配置类后三个是基于aop做的用注解切换数据源
DataSourceConfig
package com.mzd.multipledatasources.datasource; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @Configuration @MapperScan(basePackages = "com.mzd.multipledatasources.mapper", sqlSessionFactoryRef = "SqlSessionFactory") public class DataSourceConfig { @Primary @Bean(name = "test1DataSource") @ConfigurationProperties(prefix = "spring.datasource.test1") public DataSource getDateSource1() { return DataSourceBuilder.create().build(); } @Bean(name = "test2DataSource") @ConfigurationProperties(prefix = "spring.datasource.test2") public DataSource getDateSource2() { return DataSourceBuilder.create().build(); } @Bean(name = "dynamicDataSource") public DynamicDataSource DataSource(@Qualifier("test1DataSource") DataSource test1DataSource, @Qualifier("test2DataSource") DataSource test2DataSource) { Map<Object, Object> targetDataSource = new HashMap<>(); targetDataSource.put(DataSourceType.DataBaseType.TEST01, test1DataSource); targetDataSource.put(DataSourceType.DataBaseType.TEST02, test2DataSource); DynamicDataSource dataSource = new DynamicDataSource(); dataSource.setTargetDataSources(targetDataSource); dataSource.setDefaultTargetDataSource(test1DataSource); return dataSource; } @Bean(name = "SqlSessionFactory") public SqlSessionFactory test1SqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dynamicDataSource); bean.setMapperLocations( new PathMatchingResourcePatternResolver().getResources("classpath*:mapping/*.xml")); return bean.getObject(); } }
DataBaseType
package com.mzd.multipledatasources.datasource; public class DataSourceType { public enum DataBaseType { TEST01, TEST02 } // 使用ThreadLocal保证线程安全 private static final ThreadLocal<DataBaseType> TYPE = new ThreadLocal<DataBaseType>(); // 往当前线程里设置数据源类型 public static void setDataBaseType(DataBaseType dataBaseType) { if (dataBaseType == null) { throw new NullPointerException(); } System.err.println("[将当前数据源改为]:" + dataBaseType); TYPE.set(dataBaseType); } // 获取数据源类型 public static DataBaseType getDataBaseType() { DataBaseType dataBaseType = TYPE.get() == null ? DataBaseType.TEST01 : TYPE.get(); System.err.println("[获取当前数据源的类型为]:" + dataBaseType); return dataBaseType; } // 清空数据类型 public static void clearDataBaseType() { TYPE.remove(); } }
DynamicDataSource
package com.mzd.multipledatasources.datasource; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { DataSourceType.DataBaseType dataBaseType = DataSourceType.getDataBaseType(); return dataBaseType; } }
DataBaseAspect
package com.mzd.multipledatasources.datasource; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /** * @Author: xulei30 * @Date: 2021/9/4 17:55 */ @Aspect @Component public class DataBaseAspect { // @Pointcut("execution (* com.hikvision.pbg.myvls.web.modules.datasource.MasterDataBase..*.*(..))") @Pointcut("@annotation(com.mzd.multipledatasources.datasource.MasterDataBase)") public void ponitMasterMethod() { } // @Pointcut("execution (* com.hikvision.pbg.myvls.web.modules.datasource.DeliverDataBase..*.*(..))") @Pointcut("@annotation(com.mzd.multipledatasources.datasource.DeliverDataBase)") public void ponitDeliverMethod() { } @Before("ponitMasterMethod()") public void doMaterBefore(JoinPoint joinPoint) { DataSourceType.setDataBaseType(DataSourceType.DataBaseType.TEST01); } @Before("ponitDeliverMethod()") public void doDeliverBefore(JoinPoint joinPoint) { DataSourceType.setDataBaseType(DataSourceType.DataBaseType.TEST02); } }
DeliverDataBase
package com.mzd.multipledatasources.datasource; import java.lang.annotation.*; /** * @Author: xulei30 * @Date: 2021/9/4 17:50 */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DeliverDataBase { String value() default ""; }
MasterDataBase
package com.mzd.multipledatasources.datasource; import java.lang.annotation.*; /** * @Author: xulei30 * @Date: 2021/9/4 17:50 */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MasterDataBase { String value() default ""; }
application
spring.datasource.test1.url=jdbc:mysql://localhost:3306/oa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false spring.datasource.test1.username=root spring.datasource.test1.password=root123 spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver ## test2 database spring.datasource.test2.url=jdbc:mysql://localhost:3306/mhgj?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false spring.datasource.test2.username=root spring.datasource.test2.password=root123 spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver