SpringBoot项目中的多数据源配置

超、凢脫俗 2023-09-26 21:21 178阅读 0赞

通过AOP实现Mybatis多数据源切换:

yml文件配置:

  1. mybatis-plus:
  2. configuration:
  3. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印mybatis sql日志
  4. spring:
  5. datasource:
  6. druid:
  7. master-db:
  8. url: jdbc:mysql://120.0.0.1:3306/sydtjc
  9. username: root
  10. password: root
  11. mysql-db:
  12. url: jdbc:mysql://120.0.0.1:3306/ggfw
  13. username: root
  14. password: root
  15. bjggfw-db:
  16. url: jdbc:mysql://120.0.0.1:3306/ggfw_ggfw
  17. username: root
  18. password: root

自定义注解

  1. import java.lang.annotation.*;
  2. @Documented
  3. @Target({
  4. ElementType.TYPE, ElementType.METHOD})
  5. @Retention(RetentionPolicy.RUNTIME)
  6. public @interface DataSourceAnnotation {
  7. DBTypeEnum value() default DBTypeEnum.Master;
  8. }

自定义类型:

  1. public enum DBTypeEnum {
  2. Master("master"), Oracle("oracle"), Mysql("mysql"), Bjggfw("bjggfw");
  3. private String value;
  4. DBTypeEnum(String value) {
  5. this.value = value;
  6. }
  7. public String getValue() {
  8. return value;
  9. }
  10. }

公共方法:

  1. public class DbContextHolder {
  2. public static final DBTypeEnum DEFAULT_DATA_SOURCE = DBTypeEnum.Master;
  3. private static final ThreadLocal<DBTypeEnum> CONTEXT_HOLDER = new ThreadLocal<>();
  4. static {
  5. setDefaultDataSource(); // 默认指定master
  6. }
  7. /**
  8. * 设置默认数据源
  9. */
  10. public static void setDefaultDataSource() {
  11. CONTEXT_HOLDER.set(DEFAULT_DATA_SOURCE);
  12. }
  13. /**
  14. * 取得当前数据源
  15. *
  16. * @return
  17. */
  18. public static DBTypeEnum getDbType() {
  19. return CONTEXT_HOLDER.get();
  20. }
  21. /**
  22. * 设置数据源
  23. *
  24. * @param dbTypeEnum
  25. */
  26. public static void setDbType(DBTypeEnum dbTypeEnum) {
  27. CONTEXT_HOLDER.set(dbTypeEnum);
  28. }
  29. /**
  30. * 清除上下文数据
  31. */
  32. public static void clearDbType() {
  33. CONTEXT_HOLDER.remove();
  34. }
  35. }

切面类:

  1. import org.aspectj.lang.ProceedingJoinPoint;
  2. import org.aspectj.lang.annotation.Around;
  3. import org.aspectj.lang.annotation.Aspect;
  4. import org.aspectj.lang.reflect.MethodSignature;
  5. import org.springframework.stereotype.Component;
  6. import java.lang.reflect.Method;
  7. @Aspect
  8. @Component
  9. public class DynamicDataSourceAspect {
  10. @Around("@within(com.ylz.bjyf.common.multipledatasource.DataSourceAnnotation) || @annotation(com.ylz.bjyf.common.multipledatasource.DataSourceAnnotation)")
  11. public Object before(ProceedingJoinPoint point) throws Throwable {
  12. Class<?> clazz = point.getTarget().getClass();
  13. MethodSignature signature = (MethodSignature) point.getSignature();
  14. try {
  15. if (clazz.isAnnotationPresent(DataSourceAnnotation.class)) {
  16. DataSourceAnnotation annotation = clazz.getAnnotation(DataSourceAnnotation.class);
  17. DbContextHolder.setDbType(annotation.value());
  18. }
  19. Method method = clazz.getMethod(signature.getName(), signature.getParameterTypes());
  20. if (method.isAnnotationPresent(DataSourceAnnotation.class)) {
  21. // 根据注解设置数据源
  22. DataSourceAnnotation annotation = method.getAnnotation(DataSourceAnnotation.class);
  23. DbContextHolder.setDbType(annotation.value());
  24. }
  25. return point.proceed();
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. } finally {
  29. DbContextHolder.setDbType(DBTypeEnum.Master);
  30. }
  31. return null;
  32. }
  33. }

多数据源配置类:

  1. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  2. public class DynamicDataSource extends AbstractRoutingDataSource {
  3. /**
  4. * 取得当前使用哪个数据源
  5. *
  6. * @return
  7. */
  8. @Override
  9. protected Object determineCurrentLookupKey() {
  10. return DbContextHolder.getDbType();
  11. }
  12. }

配置类:

  1. import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
  2. import com.baomidou.mybatisplus.core.MybatisConfiguration;
  3. import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
  4. import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
  5. import com.ylz.bjyf.common.multipledatasource.DBTypeEnum;
  6. import com.ylz.bjyf.common.multipledatasource.DynamicDataSource;
  7. import org.apache.ibatis.plugin.Interceptor;
  8. import org.apache.ibatis.session.SqlSessionFactory;
  9. import org.apache.ibatis.type.JdbcType;
  10. import org.mybatis.spring.annotation.MapperScan;
  11. import org.springframework.beans.factory.annotation.Qualifier;
  12. import org.springframework.boot.context.properties.ConfigurationProperties;
  13. import org.springframework.context.annotation.Bean;
  14. import org.springframework.context.annotation.Configuration;
  15. import org.springframework.context.annotation.Primary;
  16. import org.springframework.transaction.annotation.EnableTransactionManagement;
  17. import javax.sql.DataSource;
  18. import java.util.HashMap;
  19. import java.util.Map;
  20. @EnableTransactionManagement
  21. @Configuration
  22. @MapperScan({
  23. "org.mohrss.leaf.**.entity", "com.ylz.bjyf.**.mapper" }) // 注意,不要扫描jpa接口,否则使用jpa时会出现问题
  24. public class MybatisPlusConfig {
  25. /**
  26. * 分页插件
  27. */
  28. @Bean
  29. public PaginationInterceptor paginationInterceptor() {
  30. return new PaginationInterceptor();
  31. }
  32. @Bean(name = "masterDb")
  33. @ConfigurationProperties(prefix = "spring.datasource.druid.master-db")
  34. public DataSource masterDb() {
  35. return DruidDataSourceBuilder.create().build();
  36. }
  37. @Bean(name = "mysqlDb")
  38. @ConfigurationProperties(prefix = "spring.datasource.druid.mysql-db")
  39. public DataSource mysqlDb() {
  40. return DruidDataSourceBuilder.create().build();
  41. }
  42. @Bean(name = "bjggfwDb")
  43. @ConfigurationProperties(prefix = "spring.datasource.druid.bjggfw-db")
  44. public DataSource bjggfwDb() {
  45. return DruidDataSourceBuilder.create().build();
  46. }
  47. /**
  48. * 动态数据源配置
  49. *
  50. * @return
  51. */
  52. @Bean
  53. @Primary
  54. public DynamicDataSource dynamicDataSource(@Qualifier("masterDb") DataSource masterDb,
  55. @Qualifier("mysqlDb") DataSource mysqlDb,
  56. @Qualifier("bjggfwDb") DataSource bjggfwDb) {
  57. DynamicDataSource dynamicDataSource = new DynamicDataSource();
  58. Map<Object, Object> targetDataSources = new HashMap<>(2);
  59. targetDataSources.put(DBTypeEnum.Master, masterDb);
  60. targetDataSources.put(DBTypeEnum.Mysql, mysqlDb);
  61. targetDataSources.put(DBTypeEnum.Bjggfw, bjggfwDb);
  62. dynamicDataSource.setTargetDataSources(targetDataSources);
  63. dynamicDataSource.setDefaultTargetDataSource(masterDb);
  64. return dynamicDataSource;
  65. }
  66. @Bean("sqlSessionFactory")
  67. public SqlSessionFactory sqlSessionFactory(DynamicDataSource dynamicDataSource) throws Exception {
  68. MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
  69. sqlSessionFactory.setDataSource(dynamicDataSource);
  70. // sqlSessionFactory.setMapperLocations(new
  71. // PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*/*Mapper.xml"));
  72. MybatisConfiguration configuration = new MybatisConfiguration();
  73. // configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
  74. configuration.setJdbcTypeForNull(JdbcType.NULL);
  75. configuration.setMapUnderscoreToCamelCase(true);
  76. configuration.setCacheEnabled(false);
  77. sqlSessionFactory.setConfiguration(configuration);
  78. sqlSessionFactory.setPlugins(new Interceptor[]{
  79. // performanceInterceptor(),OptimisticLockerInterceptor()
  80. paginationInterceptor() // 添加分页功能
  81. });
  82. // sqlSessionFactory.setGlobalConfig(globalConfiguration());
  83. return sqlSessionFactory.getObject();
  84. }
  85. }

发表评论

表情:
评论列表 (有 0 条评论,178人围观)

还没有评论,来说两句吧...

相关阅读

    相关 springboot配置数据

    需求: springboot一个模块,有些业务数据要从A 数据库获取,有些业务数据要从B数据库获取。 也就是对一些mapper.xml 是连接A数据库,对另一些mapper