Mybatis多数据源动态切换,原来这么简单!

640?wx_fmt=jpeg

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

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

字段名 类型 备注
id int 主键自增ID
name varchar 名称

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

 
  

效果图

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

640?wx_fmt=other

640?wx_fmt=other

结语

就以这段话自勉、共勉吧。越努力、越幸运,如果你不是官二代、富二代、红二代,那么请记住:勤奋才是改变你命运的唯一捷径。

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。

欢迎各位读者加入程序员知识码头技术群,在公众号后台回复“加群”即可。

640?wx_fmt=png

猜你还想看

                               

扫描方“二维码”,选择“关注公众号

每天技术文章第一时间送达!

640?wx_fmt=png

 
                                          
支持大宇,留个在看吧640?

猜你喜欢

转载自blog.csdn.net/weixin_45579804/article/details/102675291
今日推荐