1.概要
- 读写分离分为master、slave两台MySQL服务器
- 在appcation.yml配置多数据源
- 为多数据源配置读写路由
- 在AOP中根据方法名或者@Master、@Slave来选择连接不同的数据库
2.代码
spring:
banner:
location: banner.txt
datasource:
master:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: **********
slave:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/boot_mybatis_plus?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: **********
thymeleaf:
cache: false
check-template: true
check-template-location: true
encoding: UTF-8
prefix: classpath:/templates
security:
oauth2:
client:
client-id: user-client
client-secret: 123
user-authorization-uri: http://localhost:8088/oauth/authorize
access-token-uri: http://localhost:8088/oauth/token
resource:
id: user-client
user-info-uri: user-info
authorization:
check-token-access: http://localhost:8088/oauth/check_token
mybatis:
mapper-locations: classpath:/mapper/*.xml
server:
port: 8080
package com.ctgu.tools;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;
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();
}
}
package com.ctgu.tools;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value();
}
- DynamicDataSourceConfig.java
package com.ctgu.config;
import com.ctgu.tools.DynamicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class DynamicDataSourceConfig {
@Autowired
@Lazy
private DataSource masterDataSource;
@Autowired
@Lazy
private DataSource slaveDataSource;
@Bean
@Primary
public DynamicDataSource dataSource(){
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> map = new HashMap<>();
map.put("ds1", masterDataSource);
map.put("ds2", slaveDataSource);
System.out.println(map);
dynamicDataSource.setDefaultTargetDataSource(slaveDataSource);
dynamicDataSource.setTargetDataSources(map);
return dynamicDataSource;
}
}
package com.ctgu.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 javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource(){
return DruidDataSourceBuilder.create().build();
}
}
package com.ctgu.aop;
import com.ctgu.tools.DataSource;
import com.ctgu.tools.DynamicDataSource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Slf4j
@Component
public class DataSourceAspect {
@Before("execution(* com.ctgu.service..*.*(..))&&@annotation(ds)")
public void changeDataSource(JoinPoint point, DataSource ds) throws Throwable {
String key = ds.value();
System.out.println(key);
if(key != null && !key.trim().equals("")) {
DynamicDataSource.setDataSource(key);
}
}
@After("execution(* com.ctgu.service..*.*(..))&&@annotation(ds)")
public void restoreDataSource(JoinPoint point, DataSource ds) {
DynamicDataSource.clearDataSource();
}
}
package com.ctgu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* Hello world!
*/
@EnableAspectJAutoProxy
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
<?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>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ctgu</groupId>
<artifactId>ds</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
</project>
网上随便搜搜就有了,也就遇到个循环依赖问题而已,加上@Lazy和@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
就完事了
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。