笑看烟雨红尘 2022-07-22 14:58 采纳率: 77.8%
浏览 171
已结题

Spring Boot 整合 AbstractRoutingDataSource 切换数据源无效

Spring Boot 整合 AbstractRoutingDataSource 切换数据源无效
问题相关代码
@Aspect
@Component
public class DataSourceAspect {
    @Before(value = "@annotation(com.kiku.config.SwitchSource)")
    public void beforeOpt(JoinPoint joinPoint) {
        /*因为是对注解进行切面,所以这边无需做过多判定,直接获取注解的值,进行环绕,将数据源设置成远方,然后结束后,清楚当前线程数据源*/
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        SwitchSource switchSource = method.getAnnotation(SwitchSource.class);
        DataSourceHolder.setDataSource(switchSource.value());
    }

    @After(value = "@annotation(com.kiku.config.SwitchSource)")
    public void afterOpt() {
        DataSourceHolder.clearDataSource();
    }
}
@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface SwitchSource {
    String DEFAULT_NAME = "testDataSource";

    String value() default DEFAULT_NAME;
}
public class DataSourceHolder {
    private static final ThreadLocal<String> dataSources = new InheritableThreadLocal<>();

    /**
     * 设置数据源
     */
    public static void setDataSource(String datasource) {
        dataSources.set(datasource);
    }

    /**
     * 获取数据源
     */
    public static String getDataSource() {
        return dataSources.get();
    }

    /**
     * 清除数据源
     */
    public static void clearDataSource() {
        dataSources.remove();
    }
}
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceHolder.getDataSource();
    }

    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }
}
@ConfigurationProperties(prefix = "spring.datasource")
public class MybatisConfig {
    private String url;
    private String username;
    private String password;
    private String driverClassName;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }
}
@Configuration
@EnableConfigurationProperties(MybatisConfig.class)
public class MyBatisMapperScannerConfig {
    @Autowired
    private MybatisConfig mybatisConfig;
    private static String MAPPER_LOCATOIN = "classpath*:/mapper/*.xml";
    
    @Bean(name = "dataSource")
    public DataSource dataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(mybatisConfig.getUrl());
        druidDataSource.setUsername(mybatisConfig.getUsername());
        druidDataSource.setDriverClassName(mybatisConfig.getDriverClassName());
        druidDataSource.setPassword(mybatisConfig.getPassword());
        return druidDataSource;
    }
    
    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATOIN));
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        // 自动将数据库中的下划线转换为驼峰格式
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setDefaultFetchSize(100);
        configuration.setDefaultStatementTimeout(30);
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean.getObject();
    }
}
@Configuration
public class TestMybatisConfig {
    private static String MAPPER_LOCATOIN = "classpath*:/mapper/*.xml";

    @Bean(name = "testDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.test")
    public DataSource hisDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean(name = "dynamicDataSource")
    public DynamicDataSource dynamicDataSource(@Qualifier("dataSource") DataSource dataSource, @Qualifier("testDataSource") DataSource hisDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("testDataSource", hisDataSource);
        return new DynamicDataSource(dataSource, targetDataSources);
    }
    
    @Bean("sqlSessionFactory2")
    @Primary
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATOIN));
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        // 自动将数据库中的下划线转换为驼峰格式
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setDefaultFetchSize(100);
        configuration.setDefaultStatementTimeout(30);
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean.getObject();
    }
}
RestController
public class TestController {
    @Autowired
    private TestDao dao;
    
    @RequestMapping("test01")
    public String test01() {
        String name = dao.selectTest();
        return name;
    }
    
    @RequestMapping("test02")
    @SwitchSource
    public String test02() {
        String name = dao.selectTest();
        return name;
    }
}
<select id="selectTest" resultType="java.lang.String">
        select name from kiku
</select>
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode\=true&characterEncoding\=UTF-8&zeroDateTimeBehavior\=convertToNull&useSSL\=false&allowMultiQueries\=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.test.jdbc-url=jdbc:mysql://127.0.0.1:3306/testversionup?useUnicode\=true&characterEncoding\=UTF-8&zeroDateTimeBehavior\=convertToNull&useSSL\=false&allowMultiQueries\=true&serverTimezone=Asia/Shanghai
spring.datasource.test.username=root
spring.datasource.test.password=root
spring.datasource.test.driver-class-name=com.mysql.jdbc.Driver
  • 写回答

2条回答

  • kse_music 2022-07-22 18:07
    关注

    在dynamicDataSource的bean上加上@Primary

      @Bean(name = "dynamicDataSource")
        @Primary
        public DynamicDataSource dynamicDataSource(@Qualifier("dataSource") DataSource dataSource, @Qualifier("testDataSource") DataSource hisDataSource) {
            Map<Object, Object> targetDataSources = new HashMap<>();
            targetDataSources.put("testDataSource", hisDataSource);
            return new DynamicDataSource(dataSource, targetDataSources);
        }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 8月1日
  • 已采纳回答 7月24日
  • 修改了问题 7月22日
  • 创建了问题 7月22日

悬赏问题

  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决