SpringBoot结合Mybatis实现动态数据源切换

前言

在现代的分布式系统中,我们经常需要处理大量的数据和请求。为了提高系统的可扩展性和性能,我们需要使用动态数据源来管理不同的数据库连接。本文将介绍如何在SpringBoot项目中结合Mybatis实现动态数据源切换。

引入依赖

首先,我们需要在项目的pom.xml文件中添加SpringBoot、Mybatis和数据库驱动的依赖。以MySQL为例:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.4</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

配置数据源

application.ymlapplication.properties文件中配置多个数据源,例如:

yaml 复制代码
spring:
  datasource:
    dynamic:
      primary: db1 # 设置默认数据源为db1
      datasource:
        db1:
          url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
        db2:
          url: jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver

创建动态数据源类

创建一个动态数据源类,继承AbstractRoutingDataSource,重写determineCurrentLookupKey方法,根据请求参数或其他条件判断使用哪个数据源。例如:

java 复制代码
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
import java.util.*;

@Configuration
public class DataSourceConfig {
    @Bean(name = "dynamicDataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dynamicDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "primaryDataSource")
    @Primary // 设置为主数据源,当没有指定数据源时使用该数据源
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }
}

创建事务管理器和SqlSessionFactoryBean

创建一个事务管理器,使用动态数据源作为事务管理器的数据源。同时,创建一个SqlSessionFactoryBean,设置数据源和映射文件的位置。例如:

java 复制代码
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.aop.framework.autoproxy.EnableAspectJAutoProxy;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.datasource.*;
import javax.sql.DataSource;
import java.util.*;

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // @EnableTransactionManagement注解会自动启用基于注解的事务管理功能,无需额外配置。同时,它会自动启用基于XML的事务管理功能,无需额外配置。因此,只需要在主配置类上添加@EnableTransactionManagement注解即可。如果需要禁用基于XML的事务管理功能,可以在@EnableTransactionManagement注解中添加mode属性并设置为AdviceMode.ASPECTJ,如下所示:@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)。此外,如果需要禁用基于注解的事务管理功能,可以在@EnableTransactionManagement注解中添加proxyTargetClass属性并设置为true,如下所示:@EnableTransactionManagement(proxyTargetClass = true)。但是,这种方式会导致一些潜在的问题,因此不建议使用。

使用动态数据源

在需要进行数据源切换的地方,注入DynamicDataSource,然后调用其determineCurrentLookupKey方法获取当前数据源的名称,最后使用SqlSessionFactory获取对应的SqlSessionFactory实例。例如:

java 复制代码
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
import java.util.*;

@Service
public class UserService {
    @Autowired
    private DataSource dynamicDataSource;

    public void getUserById(int id) {
        Map<Object, Object> context = new HashMap<>();
        context.put("id", id);
        String currentDataSource = dynamicDataSource.determineCurrentLookupKey();
        SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) dynamicDataSource.getConnection(currentDataSource);
        // 使用sqlSessionFactory进行数据库操作...
    }
}

总结

我们可以在SpringBoot项目中实现动态数据源切换。在实际项目中,我们还可以根据业务需求对动态数据源进行更多的定制和优化。

相关推荐
麦兜*35 分钟前
Spring Boot 企业级动态权限全栈深度解决方案,设计思路,代码分析
java·spring boot·后端·spring·spring cloud·性能优化·springcloud
ruan1145142 小时前
MySQL4种隔离级别
java·开发语言·mysql
程序员爱钓鱼3 小时前
Go语言实战案例-读取用户输入并打印
后端·google·go
Hellyc6 小时前
基于模板设计模式开发优惠券推送功能以及对过期优惠卷进行定时清理
java·数据库·设计模式·rocketmq
lifallen6 小时前
Paimon LSM Tree Compaction 策略
java·大数据·数据结构·数据库·算法·lsm-tree
hdsoft_huge6 小时前
SpringBoot 与 JPA 整合全解析:架构优势、应用场景、集成指南与最佳实践
java·spring boot·架构
Livingbody7 小时前
基于【ERNIE-4.5-VL-28B-A3B】模型的图片内容分析系统
后端
百锦再7 小时前
详细解析 .NET 依赖注入的三种生命周期模式
java·开发语言·.net·di·注入·模式·依赖
程序员的世界你不懂7 小时前
基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(2)对框架加入业务逻辑层
java·selenium·maven
你的人类朋友8 小时前
🍃Kubernetes(k8s)核心概念一览
前端·后端·自动化运维