Mybatis-Plus接入多个数据源

移动开发先锋 2024-08-08 ⋅ 17 阅读

1. 前言

数据源的管理在大型项目中显得尤为重要。而Mybatis-Plus作为一个功能强大的ORM框架,可以简化我们操作数据库的流程,提高开发效率。本文主要介绍如何使用Mybatis-Plus接入多个数据源,并实现读写分离。

2. 准备工作

在开始之前,我们需要引入相应的依赖。在pom.xml中添加以下代码:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>最新版本</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>最新版本</version>
</dependency>

同时,我们还需要配置数据库信息和数据源配置信息。在application.properties文件中添加以下配置:

## 主数据源配置
spring.datasource.master.url=jdbc:mysql://localhost:3306/master?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.master.username=root
spring.datasource.master.password=root
spring.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver

## 从数据源配置
spring.datasource.slave.url=jdbc:mysql://localhost:3306/slave?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.slave.username=root
spring.datasource.slave.password=root
spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver

## Mybatis-Plus配置
mybatis-plus.mapper-locations=classpath*:mapper/**/*.xml
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.use-generated-keys=true

3. 创建数据源配置类

为了方便管理数据源,我们创建一个DataSourceConfig类,用于配置多个数据源。

@Configuration
public class DataSourceConfig {

    @Primary
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }
}

4. 创建数据源工厂类

接下来,我们创建一个数据源工厂类DynamicDataSourceFactory,用于动态获取数据源。

public class DynamicDataSourceFactory {

    public static DataSource dynamicDataSource(DataSource masterDataSource, DataSource slaveDataSource) {
        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("master", masterDataSource);
        targetDataSources.put("slave", slaveDataSource);
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(masterDataSource);
        return dataSource;
    }
}

5. 创建动态数据源

然后,我们创建一个动态数据源类DynamicRoutingDataSource,用于实现数据源的切换。

public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceKey();
    }
}

6. 创建数据源上下文

再创建一个数据源上下文类DynamicDataSourceContextHolder,用于记录当前数据源的key。

public class DynamicDataSourceContextHolder {

    private static final ThreadLocal<Object> CONTEXT_HOLDER = new ThreadLocal<>();

    public static void setDataSourceKey(String dataSourceKey) {
        CONTEXT_HOLDER.set(dataSourceKey);
    }

    public static String getDataSourceKey() {
        return CONTEXT_HOLDER.get();
    }

    public static void clearDataSourceKey() {
        CONTEXT_HOLDER.remove();
    }
}

7. 创建切换数据源的注解

为了方便切换数据源,我们可以创建一个@DataSource注解。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    String value() default "master";
}

8. 创建AOP切面类

然后,我们创建一个切面类DataSourceAspect,用于根据@DataSource注解动态切换数据源。

@Aspect
@Component
public class DataSourceAspect {

    @Around("@annotation(dataSource)")
    public Object around(ProceedingJoinPoint point, DataSource dataSource) throws Throwable {
        String dataSourceKey = dataSource.value();
        if (!StringUtils.isEmpty(dataSourceKey)) {
            DynamicDataSourceContextHolder.setDataSourceKey(dataSourceKey);
        }
        try {
            return point.proceed();
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceKey();
        }
    }
}

9. 使用多数据源

最后,我们可以在需要使用多数据源的地方使用@DataSource注解来指定使用哪个数据源。

@DataSource("master")
public interface UserMapper extends BaseMapper<User> {

    @DataSource("slave")
    List<User> findAll();
}

10. 总结

通过以上的步骤,我们成功地将Mybatis-Plus接入多个数据源,并实现了读写分离。使用多数据源可以有效地分担数据库的读写压力,提高系统的性能和稳定性。同时,我们也为项目的扩展提供了更大的灵活性。

希望本文对你有所帮助,谢谢阅读!


全部评论: 0

    我有话说: