当前位置: 首页 > news >正文

Mybatis Plus 多数据源

MyBatis Plus 的 多数据源支持是通过 DataSource 来实现的,它允许在同一个应用中同时连接多个数据库,适用于多种场景:纯粹多库、读写分离、一主多从、混合模式等

模拟一个纯粹多库的一个场景,其他场景类似

1、创建数据和表

在数据库 springbootdemo 中创建 t_employee 表,在数据库 springbootdemo1 中创建同名数据表

CREATE TABLE t_employee (id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',em_name VARCHAR(50) NOT NULL COMMENT '员工姓名',age INT DEFAULT 0 COMMENT '年龄',email VARCHAR(100) COMMENT '邮箱',department VARCHAR(100) COMMENT '部门',hire_date DATE COMMENT '入职日期',salary DECIMAL(10, 2) DEFAULT 0.00 COMMENT '薪资',version INT DEFAULT 1 COMMENT '乐观锁版本号',deleted TINYINT DEFAULT 0 COMMENT '逻辑删除标志(0:未删,1:已删)',create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='员工表';

2.引入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.0</version>
</dependency>

3.配置多数据源

spring:# 配置数据源信息datasource:dynamic:# 设置默认的数据源或者数据源组 ,默认值即为masterprimary: master# 严格匹配数据源 ,默认false.true未匹配到指定数据源时抛异常 ,false使用默认数据源strict: falsedatasource:master:url: jdbc:mysql://localhost:3306/springbootdemodriver-class-name: com.mysql.jdbc.Driverusername: rootpassword: 123456slave1:url: jdbc:mysql://localhost:3306/springbootdemo1driver-class-name: com.mysql.jdbc.Driverusername: rootpassword: 123456

4.创建IEmployeeService

EmployeeMapper

package com.goose.mapper;import com.goose.entity.Employee;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;/*** <p>* 员工表 Mapper 接口* </p>** @author goose* @since 2025-07-27*/
@Mapper
@Repository
public interface EmployeeMapper extends BaseMapper<Employee> {}

IEmployeeService

package com.goose.service;import com.goose.entity.Employee;
import com.baomidou.mybatisplus.extension.service.IService;/*** <p>* 员工表 服务类* </p>** @author goose* @since 2025-07-27*/
public interface IEmployeeService extends IService<Employee> {}

EmployeeServiceImpl

package com.goose.service.impl;import com.goose.entity.Employee;
import com.goose.mapper.EmployeeMapper;
import com.goose.service.IEmployeeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;/*** <p>* 员工表 服务实现类* </p>** @author goose* @since 2025-07-27*/
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {}

5.创建BossService

BossMapper

package com.goose.mapper;import com.goose.entity.Employee;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;/*** <p>* 员工表 Mapper 接口* </p>** @author goose* @since 2025-07-27*/
@Mapper
@Repository
public interface BossMapper extends BaseMapper<Employee> {}

IBossService

package com.goose.service;import com.goose.entity.Employee;
import com.baomidou.mybatisplus.extension.service.IService;/*** <p>* 员工表 服务类* </p>** @author goose* @since 2025-07-27*/
public interface IBossService extends IService<Employee> {}

BossServiceImpl

package com.goose.service.impl;import com.goose.entity.Employee;
import com.goose.mapper.BossMapper;
import com.goose.mapper.EmployeeMapper;
import com.goose.service.IBossService;
import com.goose.service.IEmployeeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;/*** <p>* 员工表 服务实现类* </p>** @author goose* @since 2025-07-27*/
@Service
public class BossServiceImpl extends ServiceImpl<BossMapper, Employee> implements IBossService {}

6.测试

@SpringBootTest
public class DataSourceTest {@Autowiredprivate IBossService bossService;@Autowiredprivate IEmployeeService employeeService;@Testpublic void test() {System.out.println("bossService: " + bossService.getById(1L));System.out.println("employeeService: " + employeeService.getById(1L));}
}

输出:

bossService: Employee(id=1, emName=张三, age=30, email=zhangsan@example.com, department=研发部, hireDate=2022-05-15, salary=8000.00, version=1, deleted=0, createTime=2025-07-27T16:57:54, updateTime=2025-07-27T16:57:54)
employeeService: Employee(id=1, emName=张三, age=30, email=zhangsan@example.com, department=研发部, hireDate=2022-05-15, salary=8000.00, version=1, deleted=0, createTime=2025-07-27T16:57:43, updateTime=2025-07-27T16:57:43)

7.注意

@DS 注解是MyBatis Plus中用于实现多数据源切换的功能。通过该注解,我们可以直接在方法级别指定使用哪一个数据源,这对于动态选择数据库非常有用,尤其是当你需要在某些业务操作中切换数据源(如:读写分离、按需访问不同数据库等)时。

使用场景

读写分离

在一些系统中,可能有一个主数据库负责写操作,多个副本数据库负责读操作。通过使用 @DS 注解,可以在写操作时切换到主库,读操作时切换到副本库。

多数据源应用

当系统需要同时访问多个数据源时,例如访问不同的数据库实例或数据库类型,使用 @DS 注解可以在不同方法中动态切换数据源。

不同模块的数据源配置

如果你的系统有多个模块,每个模块有自己的数据源配置(如:财务模块、用户模块等),可以通过 @DS 注解在不同模块的服务方法中指定不同的数据源。

(1)使用 @DS 注解切换数据源

假设有一个 UserService 服务类,分别要在不同的方法中使用不同的数据源。

import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.stereotype.Service;@Service
public class UserService {// 使用主数据源@DS("primary")public User getUserFromPrimaryDb(Long userId) {return userMapper.selectById(userId);  // 主数据源的操作}// 使用备份数据源@DS("secondary")public User getUserFromSecondaryDb(Long userId) {return userMapper.selectById(userId);  // 备份数据源的操作}
}
(2)控制器层的使用

在控制器层,也可以使用 @DS 注解来切换数据源。

import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {private final UserService userService;public UserController(UserService userService) {this.userService = userService;}@GetMapping("/getPrimaryUser")@DS("primary")  // 使用主数据源public User getPrimaryUser(Long userId) {return userService.getUserFromPrimaryDb(userId);}@GetMapping("/getSecondaryUser")@DS("secondary")  // 使用备份数据源public User getSecondaryUser(Long userId) {return userService.getUserFromSecondaryDb(userId);}
}

(3)注意事项

数据源配置

使用 @DS 注解之前,你需要先在 Spring 配置中定义多个数据源,并确保数据源切换机制已经启用。通常,@DS 注解依赖于动态数据源切换框架,如Dynamic DataSource插件。

方法级切换

@DS 注解是直接作用于方法的,因此每个方法都可以选择使用不同的数据源。这非常适用于需要频繁切换数据源的业务逻辑。

事务管理

如果你的方法涉及到多个数据源的操作,注意事务的管理。确保在同一个事务中不能跨数据源操作,因为 MyBatis Plus 默认情况下只会在同一个数据源内进行事务管理。若需要跨数据源事务,可能需要额外的配置或使用分布式事务管理。

性能考虑

频繁的数据源切换可能对性能产生一定影响,特别是在高并发的场景下,确保你在业务上合理使用数据源切换,避免不必要的性能开销。

数据源路由

使用 @DS 注解时,要确保数据源路由逻辑清晰,避免出现不必要的配置混乱或数据源错误。例如,某些操作应该始终使用主数据源(如写操作),而有些查询操作可以使用副本数据源。

默认数据源

如果没有显式指定数据源,系统通常会使用默认数据源。你可以通过配置或代码设置默认数据源,确保没有被 @DS 注解标注的方法也能正常运行。

@DS 注解使得 MyBatis Plus 可以根据业务需求灵活切换不同的数据源。它适用于读写分离、多个数据库并行操作等场景,提供了一种简单的方式来在方法级别上进行数据源的动态切换。

使用时需要注意:

  1. 正确配置数据源。
  2. 管理事务的正确性。
  3. 避免频繁切换数据源导致性能问题。

http://www.lryc.cn/news/601889.html

相关文章:

  • AI时代,我们更需要自己的开发方式与平台
  • Coze Studio概览(一)
  • 链表算法常用技巧与操作
  • 通过硬编码函数地址并转换为函数指针来调用函数
  • 【Agentic】通过LangGrah实现RAG评分和重写
  • 清华大学具身智能多传感器融合感知综述:背景、方法、挑战与展望
  • Flutter开发实战之CI/CD与发布流程
  • 网易大模型算法岗面经80道
  • JSON格式化与结构对比
  • 移植pbrt中的并行化到ray trace in weeks中
  • LangGraph底层API入门总结
  • OpenLayers 综合案例-地图绘制
  • 十字链表以及实现
  • SpringAI入门及浅实践,实战 Spring‎ AI 调用大模型、提示词工程、对话记忆、Adv‎isor 的使用
  • 第五章 中央处理器(CPU)知识体系与考法总结
  • 【第六节】方法与事件处理器
  • Gradle#Plugin
  • Windows---动态链接库Dynamic Link Library(.dll)
  • 2025.7.27总结—新励成
  • Kubernetes 核心组件解析
  • HCIE学习之路:MSTP实现负载均衡实验
  • 【INT范围提取字符串数字为正数】2022-8-29
  • Leetcode 3628. Maximum Number of Subsequences After One Inserting
  • rust- 定义模块以控制作用域和隐私
  • 握手未来,PostgreSQL认证专家
  • 【I】题目解析
  • Spring AI 学习笔记
  • 小架构step系列27:Hibernate提供的validator
  • 「mysql」Mac osx彻底删除mysql
  • Java面试宝典:MySQL性能优化