MyBatis-Plus如何优雅的配置多租户及分页

2024-06-03 07:28

本文主要是介绍MyBatis-Plus如何优雅的配置多租户及分页,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MyBatis-Plus如何优雅的配置多租户及分页

  • 一、配置多租户
    • 1、步骤一
    • 2、步骤二
    • 3、步骤三
    • 步骤四
  • 二、配置分页
    • 1、步骤一
    • 2、步骤二
    • 3、步骤三

一、配置多租户

TenantLineInnerInterceptorMyBatis-Plus 提供的一个插件,用于实现多租户的数据隔离。通过这个插件,可以确保每个租户只能访问自己的数据,从而实现数据的安全隔离。

1、步骤一

通过实现 TenantLineHandler 接口,处理租户相关的逻辑:

import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.util.List;@Component
public class CustomTenantHandler implements TenantHandler {@Overridepublic Expression getTenantId() {// 假设有一个租户上下文,能够从中获取当前用户的租户Long tenantId = TenantContextHolder.getCurrentTenantId();// 返回租户ID的表达式return tenantId;}@Overridepublic String getTenantIdColumn() {return "tenant_id";}@Overridepublic boolean ignoreTable(String tableName) {// 根据需要返回是否忽略该表return false;}@Overridepublic void setProperties(Properties properties) {// 可以设置一些属性}
}

2、步骤二

但在实际应用场景中会存在部分表不分租户,这时需要忽略租户过滤指定表,常规情况下我们可能会定义一个常量数据来判断,但这样不方便维护,可以通过反射判断当前表是否存在租户id字段,以此忽略租户隔离:

/*** <p>* 租户处理器* </p>** @author 瞄你个汪* @since 2024/6/2 16:15*/
@Slf4j
@Component
public class TableTenantLineHandler implements TenantLineHandler {@Autowiredprivate AppConfiguration appConfig;...@Overridepublic boolean ignoreTable(String tableName) {return Strings.isEmpty(tableName) || appConfig.notHasTenantColumn(tableName, getTenantIdColumn());}...
}

3、步骤三

判断表是否存在租户字段:


/*** <p>*  应用配置类* </p>* @author 瞄你个汪* @since 2024/5/29 12:55*/
@Data
@Component
public class AppConfiguration {...// 这里我使用了SpringBoot Cache缓存@Cacheable(value="system", key="#methodName + ':' + #tableName")public boolean notHasTenantColumn(String tableName, String tenantId) {// TableInfoHelper 为MyBatis-Plus中的工具类List<TableInfo> tableInfos = TableInfoHelper.getTableInfos();for (TableInfo table : tableInfos) {if (tableName.equals(table.getTableName())) {return table.getFieldList().stream().noneMatch(x -> tenantId.equals(x.getColumn()));}}return false;}
}

步骤四

注入租户处理器

/*** <p>* MybatisPlus 配置* </p>* @author 瞄你个汪* @since 2024/6/2 16:30*/
@Configuration
@MapperScan("top.xxxx.mapper")
public class MybatisPlusConfig {@Autowiredprivate TableTenantLineHandler tableTenantLineHandler;@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();tenantInterceptor.setTenantLineHandler(tableTenantLineHandler);interceptor.addInnerInterceptor(tenantInterceptor);return interceptor;}
}

二、配置分页

1、步骤一

编写通用分页查询接口输入参数类:

/*** <p>* Http 分页查询输入参数* </p>* @author 瞄你个汪* @since 2024-05-01 12:00:00*/
@Data
public class PageInput<S> {/*** 查询条件*/private S search;/*** 页容量*/@Min(value = 1, message = "页容量不能小于1")private long size = 10;/*** 当前页*/@Min(value = 1, message = "当前页不能小于1")private long page = 1;/*** 排序字段*/private List<OrderItem> orders;public <R> IPage<R> getPage() {Page<R> page = new Page<>(this.page, size);page.setOrders(orders);page.setMaxLimit(500L);return page;}/*** 传递分页参数并设置查询记录*/public <R> IPage<R> reader(Function<IPage<R>, List<R>> func) {IPage<R> page = getPage();return page.setRecords(func.apply(page));}/*** 传递分页参数并设置查询记录*/public <R> IPage<R> reader(BiFunction<IPage<R>, QueryWrapper<R>, List<R>> func) {IPage<R> page = getPage();return page.setRecords(func.apply(page, new QueryWrapper<>()));}
}

2、步骤二

注入分页插件:

/*** <p>* MybatisPlus 配置* </p>* @author 瞄你个汪* @since 2024/6/2 16:30*/
@Configuration
@MapperScan("top.xxxx.mapper")
public class MybatisPlusConfig {@Autowiredprivate TableTenantLineHandler tableTenantLineHandler;@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();...// 分页配置, 这行配置必须放最后interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

3、步骤三

使用:

/*** <p>* 系统用户表 前端控制器* </p>* @author 瞄你个汪* @since 2024-01-01 12:00:00*/
@Api(tags = "⚙ 系统用户管理")
@RestController()
@RequestMapping("/api/sysUser")
public class SysUserController {private final ISysUserService service;@Autowiredpublic SysUserController(SysUserServiceImpl _service) {service = _service;}/*** <p>*  分页查询系统用户数据* </p>* @param page 分页参数* @return 查询结果*/@PostMapping("page")@ApiOperation(value = "分页查询", notes = "分页查询系统用户数据")public Result<IPage<SysUser>> queryByPage(@Validated @RequestBody PageInput<String> page) {String search = page.getSearch();boolean notEmpty = Strings.isNotEmpty(search);return Result.ok(page.reader((fPage, query) -> {query.lambda().like(notEmpty, SysUser::getMobile, search).like(notEmpty, SysUser::getAccount, search).like(notEmpty, SysUser::getRealName, search).like(notEmpty, SysUser::getNickName, search);return this.service.list(fPage, query);}));}...
}

没有过滤条件:

	@PostMapping("page")@ApiOperation(value = "分页查询", notes = "分页查询系统用户数据")public Result<IPage<SysUser>> queryByPage(@Validated @RequestBody PageInput<String> page) {return Result.ok(page.reader((_page, query) -> this.service.list(_page, query)));}

这篇关于MyBatis-Plus如何优雅的配置多租户及分页的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1026336

相关文章

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Debian系和Redhat系防火墙配置方式

《Debian系和Redhat系防火墙配置方式》文章对比了Debian系UFW和Redhat系Firewalld防火墙的安装、启用禁用、端口管理、规则查看及注意事项,强调SSH端口需开放、规则持久化,... 目录Debian系UFW防火墙1. 安装2. 启用与禁用3. 基本命令4. 注意事项5. 示例配置R

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Redis MCP 安装与配置指南

《RedisMCP安装与配置指南》本文将详细介绍如何安装和配置RedisMCP,包括快速启动、源码安装、Docker安装、以及相关的配置参数和环境变量设置,感兴趣的朋友一起看看吧... 目录一、Redis MCP 简介二、安www.chinasem.cn装 Redis MCP 服务2.1 快速启动(推荐)2.

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

mybatis中resultMap的association及collectio的使用详解

《mybatis中resultMap的association及collectio的使用详解》MyBatis的resultMap定义数据库结果到Java对象的映射规则,包含id、type等属性,子元素需... 目录1.reusltmap的说明2.association的使用3.collection的使用4.总

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

mybatis-plus QueryWrapper中or,and的使用及说明

《mybatis-plusQueryWrapper中or,and的使用及说明》使用MyBatisPlusQueryWrapper时,因同时添加角色权限固定条件和多字段模糊查询导致数据异常展示,排查发... 目录QueryWrapper中or,and使用列表中还要同时模糊查询多个字段经过排查这就导致只要whe