欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > Spring Boot + MyBatis-Plus 实现 MySQL 主从复制动态数据源切换

Spring Boot + MyBatis-Plus 实现 MySQL 主从复制动态数据源切换

2025/2/24 22:08:58 来源:https://blog.csdn.net/weixin_46146718/article/details/141365680  浏览:    关键词:Spring Boot + MyBatis-Plus 实现 MySQL 主从复制动态数据源切换

Spring Boot + MyBatis-Plus 实现 MySQL 主从复制动态数据源切换

  • 一、前言
    • 1. 添加依赖
    • 2. 配置主从数据源
    • 3. 创建数据源配置类
    • 4. 创建数据源上下文
    • 5. 定义数据源类型
    • 6. 配置数据源切换
    • 7. 创建DynamicDataSourceConfig
    • 8. 创建DynamicRoutingDataSource
    • 9. 创建注解
    • 10. 使用注解


一、前言

下面是一个示例代码,展示如何在 Spring Boot 应用中实现 MySQL 主从复制的数据源动态切换。我们将使用 Spring Boot 和 MyBatis-Plus,并且结合 Spring 的动态数据源切换功能。
在这里插入图片描述

1. 添加依赖

首先,确保在 pom.xml 文件中添加了必要的依赖:

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.20</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency></dependencies>

2. 配置主从数据源

application.ymlapplication.properties 中配置主从数据源:

server:port: 8082spring:datasource:master:url: jdbc:mysql://master-db-host:3306/your_database?useSSL=falseusername: your_usernamepassword: your_passworddriver-class-name: com.mysql.cj.jdbc.Driverslave:url: jdbc:mysql://slave-db-host:3306/your_database?useSSL=falseusername: your_usernamepassword: your_passworddriver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:mapper-locations: classpath*:/mapper/**/*.xml

3. 创建数据源配置类

DataSourceConfig 中配置数据源和动态路由:

@Configuration
@Data
public class DataSourceConfig {@Value("${spring.datasource.master.url}")private String dbUrl;@Value("${spring.datasource.master.username}")private String username;@Value("${spring.datasource.master.password}")private String password;@Value("${spring.datasource.master.driver-class-name}")private String driverClassName;@Value("${spring.datasource.slave.url}")private String slaveDbUrl;@Value("${spring.datasource.slave.username}")private String slaveUsername;@Value("${spring.datasource.slave.password}")private String slavePassword;@Value("${spring.datasource.slave.driver-class-name}")private String slaveDriverClassName;@Bean@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource masterDataSource() {return DataSourceBuilder.create().driverClassName(driverClassName).url(dbUrl).username(username).password(password).build();}@Bean@ConfigurationProperties(prefix = "spring.datasource.slave")public DataSource slaveDataSource() {return DataSourceBuilder.create().driverClassName(slaveDriverClassName).url(slaveDbUrl).username(slaveUsername).password(slavePassword).build();}
}

4. 创建数据源上下文

DatabaseContextHolder 用于管理当前线程的数据源类型:

public class DatabaseContextHolder {private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();public static void setDatabaseType(DatabaseType databaseType) {contextHolder.set(databaseType);}public static DatabaseType getDatabaseType() {return contextHolder.get();}public static void clearDatabaseType() {contextHolder.remove();}
}

5. 定义数据源类型

DatabaseType 枚举定义了数据源类型:

public enum DatabaseType {MASTER,SLAVE
}

6. 配置数据源切换

使用 AOP 来控制数据源切换,可以定义一个切面来切换数据源:

@Aspect
@Component
@EnableAspectJAutoProxy
public class DataSourceAspect {@Pointcut("@annotation(com.zbbmeta.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) {DatabaseContextHolder.setDatabaseType(dataSource.type());}try {return point.proceed();} finally {DatabaseContextHolder.clearDatabaseType();}}}

7. 创建DynamicDataSourceConfig

@Configuration
@MapperScan("com.zbbmeta.mapper")
public class DynamicDataSourceConfig {@Autowiredprivate DataSource masterDataSource;@Autowiredprivate DataSource slaveDataSource;// 配置动态数据源@Bean@Primarypublic DataSource dynamicDataSource() {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DatabaseType.MASTER, masterDataSource);targetDataSources.put(DatabaseType.SLAVE, slaveDataSource);DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();dynamicDataSource.setTargetDataSources(targetDataSources);dynamicDataSource.setDefaultTargetDataSource(masterDataSource); // 设置默认数据源return dynamicDataSource;}// 配置 MyBatis 的 SqlSessionFactory@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dynamicDataSource) throws Exception {MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();sessionFactoryBean.setDataSource(dynamicDataSource);// 设置要扫描的 mapper 接口和 XML 文件路径sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));sessionFactoryBean.setTypeAliasesPackage("com.zbbmeta.entity");  // 设置实体类包路径return sessionFactoryBean.getObject();}// 配置 MyBatis 的 SqlSessionTemplate@Beanpublic SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {return new SqlSessionTemplate(sqlSessionFactory);}
}

8. 创建DynamicRoutingDataSource

public class DynamicRoutingDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DatabaseContextHolder.getDatabaseType();}
}

9. 创建注解

注解用于标记需要读操作的方法:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {DatabaseType type() default DatabaseType.SLAVE;}

10. 使用注解

@RestController
public class TutorialController {@Autowiredprivate TutorialService tutorialService;@DataSource@GetMapping("/list")public List<Tutorial> list(){return tutorialService.list();}@DataSource(type = DatabaseType.MASTER)@GetMapping("/create")public Boolean create(){Tutorial tutorial = new Tutorial();tutorial.setTitle("master");tutorial.setDescription("master");return tutorialService.save(tutorial);}
}

这个示例展示了如何使用 Spring Boot 和 MyBatis-Plus 实现 MySQL 主从复制的数据源切换。你可以根据实际情况调整配置和代码。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词