Mybatis annotation to separate reading and writing from multiple data sources
First, you need to create two libraries for testing. I use master here_ Test and slave_ Test two libraries, both of which have the same table (lazy, happy) and table structure
Table name t_ user
Two different data are added to the table to facilitate the test
The master database record name is Xiaobin and the slave database record name is Xiaoliu
Start using spring boot to integrate mybatis. First, introduce POM files
<?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> <lom@R_830_2419@.version>1.18.6</lom@R_830_2419@.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> <!-- 添加lom@R_830_2419@ 测试坐标 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lom@R_830_2419@.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>
Dynamic data source configuration
The data source used here is Druid, which realizes the switching between data sources. Use @ datasource custom annotation and configure AOP to switch
application. YML profile
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
Multi data source configuration class
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<Object,Object> targetDataSources = new HashMap<>(); targetDataSources.put("xiaobin-master",xiaobinMasterDataSource); targetDataSources.put("xiaobin-slave",xiaobinSlaveDataSource); return new DynamicDataSource(xiaobinMasterDataSource,targetDataSources); } }
Dynamic data source switching class
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<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(); } }
Custom @ datasource annotation
Add this annotation to Dao that needs to switch data
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 section class configuration
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(); } } }
Start the configuration annotation information, which is important (otherwise an error will be reported during operation)
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); } }
Test 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<TUser> list(@PathVariable("name")String name){ if(name.equals("master")){ return userMapper.queryAllWithMaster(); }else{ return userMapper.queryAllWithSlave(); } } }
design sketch
More path value transfer, master-slave data source switching
directory structure
Source address (the database needs to be created by yourself) https://gitee.com/MyXiaoXiaoB...
summary
The above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. Thank you for your support.