在Spring boot 中使用@master 设置主从数据库
基础配置
application.yml
spring:
datasource:
master:
url: jdbc:mysql://localhost:3306/master_db
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
url: jdbc:mysql://localhost:3306/slave_db
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml
DataSourceConfig
package com.example.multids.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; @Configuration public class DataSourceConfig { // 主数据源配置(前缀对应application.yml中的spring.datasource.master) @Bean @ConfigurationProperties(prefix = "spring.datasource.master") public DataSource masterDataSource() { return DataSourceBuilder.create().build(); } // 从数据源配置 @Bean @ConfigurationProperties(prefix = "spring.datasource.slave") public DataSource slaveDataSource() { return DataSourceBuilder.create().build(); } // 动态数据源路由 @Bean public DataSource routingDataSource(DataSource masterDataSource, DataSource slaveDataSource) { AbstractRoutingDataSource routingDataSource = new AbstractRoutingDataSource() { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceType(); } }; Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("master", masterDataSource); targetDataSources.put("slave", slaveDataSource); routingDataSource.setDefaultTargetDataSource(masterDataSource); routingDataSource.setTargetDataSources(targetDataSources); return routingDataSource; } }
DataSourceContextHolder
package com.example.multids.config; public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); // 设置当前线程数据源类型 public static void setDataSourceType(String dsType) { contextHolder.set(dsType); } // 获取当前线程数据源类型 public static String getDataSourceType() { return contextHolder.get(); } // 清除数据源类型 public static void clearDataSourceType() { contextHolder.remove(); } }
Master
package com.example.multids.annotation; import java.lang.annotation.*; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Master { // 标记使用主数据源 }
DataSourceAspect
package com.example.multids.aspect; import com.example.multids.annotation.Master; import com.example.multids.config.DataSourceContextHolder; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Aspect @Component @Order(-1) // 保证在事务注解前执行 public class DataSourceAspect { @Around("@annotation(master)") public Object around(ProceedingJoinPoint point, Master master) throws Throwable { try { DataSourceContextHolder.setDataSourceType("master"); return point.proceed(); } finally { DataSourceContextHolder.clearDataSourceType(); } } }
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>

浙公网安备 33010602011771号