Mybatis注解实现多数据源读写分离详解

网友投稿 256 2022-12-26


Mybatis注解实现多数据源读写分离详解

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

表名 t_user

| 字段名 | 类型 | 备注 |

| :------: | :------: | :------: |

| id | int | 主键自增ID |

| name | varchar | 名称 |

表中分别添加两条不同数据,方便测试

主数据库记录name为xiaobin,从库为xiaoliu

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

xmlns:xsi="http://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">

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

xmlns:xsi="http://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">

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

多数据源配置类

package com.xiaobin.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;

import org.springframework.boot.context.properties.ConfigurationProperties;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Primary;

import org.springframework.stereotype.Component;

import javax.sql.DataSource;

import java.util.HashMap;

import java.util.Map;

/**

* 创建时间: 2019/9/22 11:42

* 备注:多数据源配置信息

* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事

**/

@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 targetDataSources = new HashMap<>();

targetDataSources.put("xiaobin-master",xiaobinMasterDataSource);

targetDataSources.put("xiaobin-slave", xiaobinSlaveDataSource);

return new DynamicDataSource(xiaobinMasterDataSource, targetDataSources);

}

}

动态数据源切换类

package com.xiaobin.config;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import org.springframework.lang.Nullable;

import javax.sql.DataSource;

import java.util.Map;

/**

* 创建时间: 2019/9/22 11:51

* 备注:动态数据源

* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事

**/

public class DynamicDataSource extends AbstractRoutingDataSource {

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

public DynamicDataSource(DataSource defaultTargetDataSource, Map 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添加此注解

package com.xiaobin.annotation;

import java.lang.annotation.*;

/**

* 创建时间: 2019/9/22 11:53

* 备注:自定义数据源选择注解

* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事

**/

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface DataSource {

String name() default "";

}

Aop切面类配置

package com.xiaobin.aspect;

import com.xiaobin.annotation.DataSource;

import com.xiaobin.config.DynamicDataSource;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**

* 创建时间: 2019/9/22 11:54

* 备注:

* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事

**/

@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();

}

}

}

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

package com.xiaobin;

import com.xiaobin.config.DynamicDataSourceConfig;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

import org.springframework.context.annotation.Import;

/**

* 创建时间: 2019/9/22 11:17

* 备注:

* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事

**/

@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

package com.xiaobin.api;

import com.xiaobin.Entity.TUser;

import com.xiaobin.mapper.UserMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**

* 创建时间: 2019/9/22 12:08

* 备注:

* 码农自学交流小群:260532022,欢迎大家的加入,分享学习是一件开心事

**/

@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();

}

}

}

效果图

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

目录结构

源码地址(数据库需要自己创建)https://gitee.com/MyXiaoXiaoB...

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:应用系统接口设计要求(应用系统集成接口规范)
下一篇:Java8深入学习之熟透Optional
相关文章

 发表评论

暂时没有评论,来抢沙发吧~