Springboot整合mysql主从架构
时间: 2025-01-14 13:29:49 浏览: 38
### Spring Boot与MySQL主从架构集成
#### 配置数据源
为了使Spring Boot应用程序能够连接到MySQL数据库并支持读写分离,在`application.yml`文件中配置两个不同的数据源:一个是用于写的主节点,另一个是用于读取操作的从节点。
```yaml
spring:
datasource:
master:
url: jdbc:mysql://master_host:port/dbname?useSSL=false&serverTimezone=UTC
username: root
password: pwd
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
url: jdbc:mysql://slave_host:port/dbname?useSSL=false&serverTimezone=UTC
username: root
password: pwd
driver-class-name: com.mysql.cj.jdbc.Driver
```
#### 创建自定义DataSourceRouter类
通过创建一个名为`DynamicDataSource`的类来管理多个数据源之间的切换逻辑。此方法允许动态决定当前请求应该访问哪个具体的数据库实例[^1]。
```java
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}
```
#### 实现线程局部变量存储机制
引入了一个简单的工具类叫做`DataSourceContextHolder`用来保存当前事务上下文中所使用的数据源名称。这有助于在线程内部保持一致性,并确保每次查询都能正确指向预期的目标库[^2]。
```java
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}
public static String getDataSourceType() {
return (contextHolder.get());
}
public static void clearDataSourceType() {
contextHolder.remove();
}
}
```
#### 定义AOP切面拦截器
利用面向方面的编程(AOP),可以轻松地控制何时以及如何改变正在使用的数据源。例如,可以在执行任何持久化层的方法之前设置适当的数据源键值[^3]。
```java
@Aspect
@Component
public class DataSourceAspect {
@Around("@annotation(com.example.annotation.DataSource)")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature)point.getSignature();
Method method = signature.getMethod();
if(method.isAnnotationPresent(DataSource.class)){
DataSource source = method.getAnnotation(DataSource.class);
DataSourceContextHolder.setDataSourceType(source.value().name());
}else{
DataSourceContextHolder.clearDataSourceType();
}
try {
return point.proceed();
} finally {
DataSourceContextHolder.clearDataSourceType(); // 清除数据源信息以便后续其他业务能正常获取默认数据源
}
}
}
```
#### 使用注解指定目标数据源
最后一步是在服务层或DAO接口上添加特定于每个操作类型的注释,比如`@Master`表示该操作应发送给主服务器;而`@Slave`则意味着它会被路由至只读副本之一处理[^4]。
```java
package com.example.annotation;
import java.lang.annotation.*;
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
Datasource value() default Datasource.SLAVE;
}
enum Datasource { MASTER, SLAVE }
```
阅读全文
相关推荐



















