首先需要建立两个库进行测试,我这里使用的是master_test和slave_test两个库,两张库都有一张同样的表(偷懒),表名 t_user
字段名 类型 备注
id int 主键自增ID
name varchar 名称
表中分别添加两条不同数据,方便测试 主数据库记录name为xiaobin,从库为xiaoliu。
目录结构
开始使用Springboot 整合mybatis,首先引入pom文件。
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.4.RELEASE
com.xiaobin
mysql_master_slave
1.0-SNAPSHOT
1.8
1.18.6
1.3.2
1.18.6
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
${lombok.version}
org.springframework.boot
spring-boot-starter-test
org.projectlombok
lombok
${lombox.version}
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.version}
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-jdbc
com.alibaba
druid-spring-boot-starter
1.1.10
org.springframework.boot
spring-boot-starter-aop
动态数据源配置
这里使用的数据源为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
动态数据源切换类
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal contextHolder = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map
自定义@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 list(@PathVariable("name")String name){
if(name.equals("master")){
return userMapper.queryAllWithMaster();
}else{
return userMapper.queryAllWithSlave();
}
}
}
效果图
更具路径传值,进行主从数据源切换