MyBatis-Plus 多数据源配置
发布时间:2025-05-21 21:41:43 发布人:远客网络
一、MyBatis-Plus 多数据源配置
1、在我们实际业务开发中,有时需要同时涉及多个数据库,可能一个 API中所需要的数据,往往是包含了多个数据库中的数据,这个时候我们就需要在项目运行中,切换数据源。
2、步骤一:我们先需要引入maven配置,版本可自选。dynamic-datasource-spring-boot-starter是一个基于springboot的快速集成多数据源的启动器。
3、步骤二:多数据源配置,需要注意的后面都有写注释。
4、步骤三:步骤三就可以直接使用啦,真的是太方便了,@DS可以注解在方法上或类上,同时存在就近原则方法上注解优先于类上注解。
5、 1,本框架只做切换数据源这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
6、 2,配置文件所有以下划线 _分割的数据源首部即为组的名称,相同组名称的数据源会放在一个组下。
7、 3,切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。
8、 4,默认的数据源名称为 master,你可以通过 spring.datasource.dynamic.primary修改。
9、 5,强烈建议只在service的类和方法上添加注解,不建议在mapper上添加注解。
二、Mybatis-plus多数据源深度剖析
在业务场景中,当需要操作多个数据库(如用户查询、订单插入)并实现读写分离时,Mybatis-plus的多数据源功能显得尤为重要。本文将深入剖析其实现策略、问题与挑战以及创建流程。
面对复杂需求,关键在于解决三个核心问题:数据源配置、管理与 ORM框架的无缝集成。在考虑了现有的解决方案后,Mybatis-plus提供了灵活的自定义选项,如通过 AOP(面向切面编程)结合 ThreadLocal实现动态数据源切换,例如动态数据源动态管理(Dynamic-datasource)组件。
AOP+ ThreadLocal:例如借助 ShardingSphere的 JDBC客户端与服务端组件。
语义解析:客户端和服务器端的协同工作,如 ShardingSphere-Proxy。
尽管便利,但多数据源管理也伴随着一些问题,如事务一致性、嵌套数据源切换,以及如何处理 Mybatis-plus特性如数据源分组、负载均衡、加密和延迟初始化等。
从 DynamicDataSourceAutoConfiguration入口,通过查找多数据源对象,实现动态路由到不同数据源。Mybatis-plus封装了 DynamicRoutingDataSource,兼容单数据源框架,同时处理切换逻辑。
DynamicRoutingDataSource的关键属性包括分组标识符和多个数据源,而 YmlDynamicDataSourceProvider则从 YAML配置文件加载这些信息。创建流程涉及自动配置,以及对 AbstractDataSourceProvider和工厂模式(如 DefaultDataSourceCreator)的使用,确保数据源的动态管理和初始化。
在底层实现中,如 DruidDataSource创建,涉及到加密和初始化过程。通过 EncDataSourceInitEvent和 ScriptRunner,确保数据源安全和表结构的正确性。
总结:Mybatis-plus的多数据源设计巧妙地整合了多个数据库操作,同时处理事务管理与高级特性。通过AOP和动态数据源管理,巧妙地解决了单数据源框架的集成难题,但需注意事务一致性与嵌套切换等问题。
在实际使用中,如在 OrderInfoController的插入操作中,通过 TenantContextHolder设置路由key,根据业务需求动态切换数据源,如插入操作分别使用master和order数据源。
三、Mybatis-Plus实现多数据源配置切换
实现Mybatis-Plus的多数据源配置切换,主要涉及依赖导入、数据库配置以及使用注解@DS来实现数据源切换。具体步骤如下:
1.首先,需要在项目中加入Mybatis-Plus多数据源依赖。在项目的pom.xml文件中,添加以下代码段:
2.接着,进行数据库配置。在配置类中,实现DruidDataSource的配置,创建多个DataSource实例,每个实例对应不同的数据源。
public class DataSourceConfig{
@Value("${spring.datasource.url}")
@Value("${spring.datasource.username}")
@Value("${spring.datasource.password}")
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.initial-size}")
@Value("${spring.datasource.min-idle}")
@Value("${spring.datasource.max-active}")
@Value("${spring.datasource.max-wait}")
@Value("${spring.datasource.time-between-eviction-runs-millis}")
private long timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.min-evictable-idle-time-millis}")
private long minEvictableIdleTimeMillis;
@Value("${spring.datasource.validation-query}")
private String validationQuery;
@Value("${spring.datasource.test-while-idle}")
private boolean testWhileIdle;
@Value("${spring.datasource.test-on-borrow}")
private boolean testOnBorrow;
@Value("${spring.datasource.test-on-return}")
private boolean testOnReturn;
@Value("${spring.datasource.pool-prepared-statements}")
private boolean poolPreparedStatements;
@Value("${spring.datasource.max-pool-prepared-statements}")
private int maxPoolPreparedStatements;
public DataSource dataSource(){
DruidDataSource dataSource= new DruidDataSource();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setDriverClassName(driverClassName);
dataSource.setInitialSize(initialSize);
dataSource.setMinIdle(minIdle);
dataSource.setMaxActive(maxActive);
dataSource.setMaxWait(maxWait);
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
dataSource.setValidationQuery(validationQuery);
dataSource.setTestWhileIdle(testWhileIdle);
dataSource.setTestOnBorrow(testOnBorrow);
dataSource.setTestOnReturn(testOnReturn);
dataSource.setPoolPreparedStatements(poolPreparedStatements);
dataSource.setMaxPoolPreparedStatements(maxPoolPreparedStatements);
public DataSource dataSource1(){
DruidDataSource dataSource= new DruidDataSource();
dataSource.setUrl("your_url1");
dataSource.setUsername("your_username1");
dataSource.setPassword("your_password1");
dataSource.setDriverClassName("your_driver_class_name1");
public DataSource dataSource2(){
DruidDataSource dataSource= new DruidDataSource();
dataSource.setUrl("your_url2");
dataSource.setUsername("your_username2");
dataSource.setPassword("your_password2");
dataSource.setDriverClassName("your_driver_class_name2");
3.使用@DS注解进行数据源切换。在需要使用不同数据源的Service、Mapper或Repository类上,通过@DS注解指定对应的数据源名称。如果在方法上也添加了@DS注解,优先级更高。
public class UserServiceImpl implements UserService{
private UserMapper userMapper;
通过上述步骤,成功实现了Mybatis-Plus多数据源配置切换,能够根据不同需求灵活选择不同的数据源进行操作,提升系统扩展性和维护性。