
MyBatis-Plus 租户同时查多个
技术介绍
MyBatis-Plus 是一款基于 MyBatis 的增强工具,在简化 MyBatis 的操作的基础上,提供了许多常用功能。租户模式是多租户架构中常用的一种实现方式,它允许多个租户共享同一套应用系统,在数据库操作层面上,通过字段或表的区分确保数据的隔离。
本文旨在介绍如何在 MyBatis-Plus 中实现租户模式下同时查询多个租户的数据。我们将通过示例逐步讲解相关配置和操作步骤,确保多租户查询的高效性及正确性。
准备工作
- 引入依赖
com.baomidou
mybatis-plus-boot-starter
x.x.x
org.springframework.boot
spring-boot-starter-data-jpa
基本配置
- 配置租户Interceptor
首先,创建一个租户拦截器,通过实现 MybatisPlusInterceptor 并配置相关租户信息。采用字段进行描述。
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.baomidou.mybatisplus.annotation.TableName;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor());
return interceptor;
}
}
- 定义租户数据源
在数据表中添加一个 tenant_id 字段,以标识数据所属的租户。
@TableName("example_table")
public class Example {
private Long id;
private String name;
private Long tenantId; // 租户ID
}
- 自定义租户处理逻辑
通过实现 TenantHandler 接口, 提供获取租户ID的方法。
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
public class CustomTenantHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 假设通过 ThreadLocal 或者 ContextHolder 获取当前用户的租户ID
Long tenantId = getCurrentUserTenantId();
setFieldValByName("tenantId", tenantId, metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
// 更新时可以额外添加更新逻辑
}
}
查询多个租户的数据
- 使用Wrapper构造查询条件
我们需要使用 QueryWrapper 来构造查询条件,并通过链式调用设置租户ID的列表。
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
public List queryMultipleTenants(List tenantIds) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.in("tenant_id", tenantIds);
return exampleMapper.selectList(queryWrapper);
}
- 示例代码实现
以下是一个完整的查询多个租户的示例代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/example")
public class ExampleController {
@Autowired
private ExampleMapper exampleMapper;
@GetMapping("/multi-tenant")
public List getMultipleTenants(@RequestParam List tenantIds) {
return queryMultipleTenants(tenantIds);
}
private List queryMultipleTenants(List tenantIds) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.in("tenant_id", tenantIds);
return exampleMapper.selectList(queryWrapper);
}
}
注意事项
- 确保数据库中的表结构与租户逻辑一致,特别是
tenant_id字段必须存在。 - 在查询多个租户数据时,注意数据量可能较大,建议使用分页查询,避免一次性加载所有数据。
- 实现租户处理逻辑时,应考虑线程安全,避免不同线程获取到错误的租户ID。
实用技巧
- 分页查询
- 动态表名交换
使用 MyBatis-Plus 提供的 Page 对象实现分页查询可以减少内存占用和提升查询性能。
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
public Page queryMultipleTenantsWithPage(List tenantIds, int pageNum, int pageSize) {
Page page = new Page(pageNum, pageSize);
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.in("tenant_id", tenantIds);
return exampleMapper.selectPage(page, queryWrapper);
}
在某些情况下,可能需要为每个租户分配独立的表名。这可以通过构建动态 SQL 逻辑实现,具体实现可参考 MyBatis 的动态 SQL 特性。
总结
通过以上步骤,您可以在 MyBatis-Plus 中实现租户模式同时查询多个租户的数据。合理配置和使用 MyBatis-Plus 的功能,将大大方便多租户应用的开发和维护。



