Spring Boot项目MySQL数据源切换


prtyaa
prtyaa 2024-01-07 22:10:24 53871 赞同 0 反对 0
分类: 资源 标签: 运维
由于在主库发现的我的一条SQL的慢查询、之前都是直接连一个数据库、后面让他改成查询的SQL连另一台从库。 于是我第一时间打开了大家的百度、后续总结复制粘贴了一个完整的案例并线上使用了、环境版本不一样可能使用的配置不一样、所以仅供参考。

Spring Boot、Druid、Mybatis、MySQL


    org.springframework.boot
    spring-boot-starter-parent
    2.3.3.RELEASE



    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    2.1.2



    mysql
    mysql-connector-java
    5.1.25



    com.alibaba
    druid-spring-boot-starter
    1.1.17

spring:
  datasource:
    master:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: 123456
    slave:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: 123456
      # druid 连接池配置接着往下配置就OK
      max-active: 12
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
    public static final String MASTER = "MASTER"; // 写
    public static final String SLAVE = "SLAVE"; // 读
    private static final ThreadLocal DYNAMIC_DATASOURCE_KEY = new ThreadLocal();
    public static String getDynamicDataSourceKey() {
        String val = DYNAMIC_DATASOURCE_KEY.get();
        return val == null ? DynamicDataSource.MASTER : val;
    }
    public static void setDynamicDataSourceKey(String key) {
        DYNAMIC_DATASOURCE_KEY.set(key);
    }
    public static void removeDynamicDataSourceKey() {
        DYNAMIC_DATASOURCE_KEY.remove();
    }
    @Override
    protected Object determineCurrentLookupKey() {
        String dynamicDataSourceKey = getDynamicDataSourceKey();
        log.info("当前数据源:[{}]", dynamicDataSourceKey);
        return dynamicDataSourceKey;
    }
}
@Configuration
public class DataSourceConfiguration {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DruidDataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DruidDataSourceBuilder.create().build();
    }
    @Bean("dynamicDataSource")
    public DynamicDataSource dynamicDataSource() {
        DynamicDataSource dynamicRoutingDataSource = new DynamicDataSource();
        Map targetDataSources = new HashMap(2);
        targetDataSources.put(DynamicDataSource.MASTER, masterDataSource());
        targetDataSources.put(DynamicDataSource.SLAVE, slaveDataSource());

        dynamicRoutingDataSource.setDefaultTargetDataSource(slaveDataSource());
        dynamicRoutingDataSource.setTargetDataSources(targetDataSources);
        dynamicRoutingDataSource.afterPropertiesSet();
        return dynamicRoutingDataSource;
    }
    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource datasource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(datasource);
        // 映射文件地址
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        // 所有Entity别名类所在包
        bean.setTypeAliasesPackage("com.suka.entity");
        return bean.getObject();
    }
}
@Slf4j
@Aspect
@Order(1)
@Component
public class DataSourceAspect {
    @Pointcut("execution(* com.suka.mapper.*.*(..))")
    public void dsPointCut() {
    }
    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        String methodName = signature.getMethod().getName();
        // get/sel/select/find 开的头的Mapper类中的方法就切换。
        if (methodName.startsWith("get") || methodName.startsWith("sel")
                || methodName.startsWith("select") || methodName.startsWith("find")) {
            DynamicDataSource.setDynamicDataSourceKey(DynamicDataSource.SLAVE);
        }
        try {
            return point.proceed();
        } finally {
            DynamicDataSource.removeDynamicDataSourceKey();
        }
    }
}

两个注意点:DataSourceAspect类是需要引入AOP依赖、sqlSessionFactory是Mybatis需要的、里面可以配置一些扫描包的配置以及类别名之类相关Mybatis的配置信息。

问题来了、如何校验我这个查询方法或者插入方法是走的那个配置的数据源呢、你去把配置文件中的数据库写一个错的不就可以校验了、如果报错了就证明是用的这个配置的数据源!!!

如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
prtyaaL2
粉丝 1 资源 1949 + 关注 私信
最近热门资源
银河麒麟桌面操作系统备份用户数据  127
统信桌面专业版【全盘安装UOS系统】介绍  122
银河麒麟桌面操作系统安装佳能打印机驱动方法  116
银河麒麟桌面操作系统 V10-SP1用户密码修改  105
麒麟系统连接打印机常见问题及解决方法  8
最近下载排行榜
银河麒麟桌面操作系统备份用户数据 0
统信桌面专业版【全盘安装UOS系统】介绍 0
银河麒麟桌面操作系统安装佳能打印机驱动方法 0
银河麒麟桌面操作系统 V10-SP1用户密码修改 0
麒麟系统连接打印机常见问题及解决方法 0
作者收入月榜
1

prtyaa 收益393.62元

2

zlj141319 收益218元

3

1843880570 收益214.2元

4

IT-feng 收益209.13元

5

风晓 收益208.24元

6

777 收益172.71元

7

Fhawking 收益106.6元

8

信创来了 收益105.84元

9

克里斯蒂亚诺诺 收益91.08元

10

技术-小陈 收益79.5元

请使用微信扫码

加入交流群

请使用微信扫一扫!