Springboot 整合Mybatis多数据源并动态切换

640?wx_fmt=jpeg

作者:hy_xiaobin
来源:https://juejin.im/post/5d8705e65188253f4b629f47

首先需要建立两个库进行测试,我这里使用的是master_test和slave_test两个库,两张库都有一张同样的表(偷懒),表名  t_user

字段名类型备注
idint主键自增ID
namevarchar名称

640?wx_fmt=jpeg

表中分别添加两条不同数据,方便测试 主数据库记录name为xiaobin,从库为xiaoliu。
目录结构

640?wx_fmt=other

开始使用Springboot 整合mybatis,首先引入pom文件。

   <?xml version="1.0" encoding="UTF-8"?>	
<project xmlns="http://maven.apache.org/POM/4.0.0"	
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"	
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">	
   <modelVersion>4.0.0</modelVersion>	
   <parent>	
       <groupId>org.springframework.boot</groupId>	
       <artifactId>spring-boot-starter-parent</artifactId>	
       <version>2.1.4.RELEASE</version>	
   </parent>	
   <groupId>com.xiaobin</groupId>	
   <artifactId>mysql_master_slave</artifactId>	
   <version>1.0-SNAPSHOT</version>	

	
   <properties>	
       <java.version>1.8</java.version>	
       <lombok.version>1.18.6</lombok.version>	
       <mybatis.version>1.3.2</mybatis.version>	
       <lombox.version>1.18.6</lombox.version>	
   </properties>	

	
   <dependencies>	
       <!-- 添加web启动坐标 -->	
       <dependency>	
           <groupId>org.springframework.boot</groupId>	
           <artifactId>spring-boot-starter-web</artifactId>	
       </dependency>	
       <!-- 添加lombok工具坐标 -->	
       <dependency>	
           <groupId>org.projectlombok</groupId>	
           <artifactId>lombok</artifactId>	
           <version>${lombok.version}</version>	
       </dependency>	
       <!-- 添加springboot 测试坐标 -->	
       <dependency>	
           <groupId>org.springframework.boot</groupId>	
           <artifactId>spring-boot-starter-test</artifactId>	
       </dependency>	
       <!-- 添加lombox 测试坐标 -->	
       <dependency>	
           <groupId>org.projectlombok</groupId>	
           <artifactId>lombok</artifactId>	
           <version>${lombox.version}</version>	
       </dependency>	
       <!-- 添加mybatis依赖坐标 -->	
       <dependency>	
           <groupId>org.mybatis.spring.boot</groupId>	
           <artifactId>mybatis-spring-boot-starter</artifactId>	
           <version>${mybatis.version}</version>	
       </dependency>	
       <!-- 添加mysql驱动器坐标 -->	
       <dependency>	
           <groupId>mysql</groupId>	
           <artifactId>mysql-connector-java</artifactId>	
       </dependency>	
       <dependency>	
           <groupId>org.springframework.boot</groupId>	
           <artifactId>spring-boot-starter-jdbc</artifactId>	
       </dependency>	
       <!-- 添加druid数据源坐标 -->	
       <dependency>	
           <groupId>com.alibaba</groupId>	
           <artifactId>druid-spring-boot-starter</artifactId>	
           <version>1.1.10</version>	
       </dependency>	
       <!-- 添加AOP坐标 -->	
       <dependency>	
           <groupId>org.springframework.boot</groupId>	
           <artifactId>spring-boot-starter-aop</artifactId>	
       </dependency>	

	
   </dependencies>	
</project>

动态数据源配置

这里使用的数据源为druid,实现数据源之间的切换用@DataSource自定义注解,配置Aop进行切换 application.yml 配置文件。

spring:	
    datasource:	
        type: com.alibaba.druid.pool.DruidDataSource	
        druid:	
          xiaobin-master: # 主数据源	
            driverClassName: com.mysql.jdbc.Driver	
            username: root	
            password: root	
            url: jdbc:mysql://localhost:3306/master_test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8	
          xiaobin-slave: # 从数据源	
            driverClassName: com.mysql.jdbc.Driver	
            username: root	
            password: root	
            url: jdbc:mysql://localhost:3306/slave_test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8	
mybatis:	
 mapper-locations: classpath:mapper/*.xml

 多数据源配置类

@Configuration	
@Component	
public class DynamicDataSourceConfig {	

	
    @Bean	
    @ConfigurationProperties("spring.datasource.druid.xiaobin-master")	
    public DataSource  xiaobinMasterDataSource(){	
        return DruidDataSourceBuilder.create().build();	
    }	

	
    @Bean	
    @ConfigurationProperties("spring.datasource.druid.xiaobin-slave")	
    public DataSource  xiaobinSlaveDataSource(){	
        return DruidDataSourceBuilder.create().build();	
    }	

	
    @Bean	
    @Primary	
    public DynamicDataSource dataSource(DataSource xiaobinMasterDataSource, DataSource xiaobinSlaveDataSource) {	
        Map<Object, Object> targetDataSources = new HashMap<>();	
        targetDataSources.put("xiaobin-master",xiaobinMasterDataSource);	
        targetDataSources.put("xiaobin-slave", xiaobinSlaveDataSource);	
        return new DynamicDataSource(xiaobinMasterDataSource, targetDataSources);	
    }	
}
动态数据源切换类
public class DynamicDataSource  extends AbstractRoutingDataSource {	

	
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();	

	
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {	
        super.setDefaultTargetDataSource(defaultTargetDataSource);	
        super.setTargetDataSources(targetDataSources);	
        super.afterPropertiesSet();	
    }	

	
    @Override	
    protected Object determineCurrentLookupKey() {	
        return getDataSource();	
    }	

	
    public static void setDataSource(String dataSource) {	
        contextHolder.set(dataSource);	
    }	

	
    public static String getDataSource() {	
        return contextHolder.get();	
    }	

	
    public static void clearDataSource() {	
        contextHolder.remove();	
    }	
}	

自定义@DataSource注解

在需要切换数据的Dao添加此注解

/**	
 * 备注:自定义数据源选择注解	
 **/	
@Target(ElementType.METHOD)	
@Retention(RetentionPolicy.RUNTIME)	
@Documented	
public @interface DataSource {	
    String name() default "";	
}	

Aop切面类配置
@Aspect	
@Component	
public class DataSourceAspect {	

	
    @Pointcut("@annotation(com.xiaobin.annotation.DataSource)")	
    public void dataSourcePointCut() {	

	
    }	

	
    @Around("dataSourcePointCut()")	
    public Object around(ProceedingJoinPoint point) throws Throwable {	
        MethodSignature signature = (MethodSignature) point.getSignature();	
        Method method = signature.getMethod();	

	
        DataSource dataSource = method.getAnnotation(DataSource.class);	
        if(dataSource == null){	
            DynamicDataSource.setDataSource("xiaobin-master");	
        }else {	
            DynamicDataSource.setDataSource(dataSource.name());	
        }	

	
        try {	
            return point.proceed();	
        } finally {	
            DynamicDataSource.clearDataSource();	
        }	
    }	
}

启动配置注解信息,重要(不然运行会报错)

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})	
@MapperScan(basePackages = "com.xiaobin.mapper")	
@Import({DynamicDataSourceConfig.class})	
public class StartApp {	
    public static void main(String[] args) {	
        SpringApplication.run(StartApp.class);	
    }	
}

测试controller

@RestController	
@RequestMapping	
public class UserController {	

	
    @Autowired	
    private UserMapper userMapper;	

	
    @GetMapping("/{name}/list")	
    public List<TUser> list(@PathVariable("name")String name){	
        if(name.equals("master")){	
            return userMapper.queryAllWithMaster();	
        }else{	
            return userMapper.queryAllWithSlave();	
        }	
    }	
}

效果图

更具路径传值,进行主从数据源切换

640?wx_fmt=other

640?wx_fmt=other

640?wx_fmt=jpeg

推荐程序员必备微信号 

JAVA
微信号:

javabaiwen

推荐理由:
在多学一点知识,就可以少写一行代码!专注于技术资源分享,经验交流,最新技术解读,另有海量免费电子书以及成套学习资源,关注JAVA,做技术得先驱者。
 ▼长按下方↓↓↓二维码识别关注
640?wx_fmt=png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值