MyBatisPlus 多租户 分页
时间: 2024-02-10 13:03:12 浏览: 85
MyBatisPlus中的多租户分页是通过配置分页插件来实现的。首先,需要在MyBatisPlus的配置类中添加分页插件的配置。配置类需要添加`@Configuration`、`@EnableTransactionManagement`、`@MapperScan`注解,并且需要注入`preTenantHandler`。在配置类中创建`PaginationInterceptor`对象,并添加攻击SQL阻断解析器和多租户拦截器到解析链中。多租户拦截器需要设置`preTenantHandler`作为租户处理器。最后,将配置好的`PaginationInterceptor`对象返回。
相关问题
mybatisplus分页拦截器+租户拦截器
### MyBatisPlus 中分页拦截器与租户拦截器的功能集成
#### 功能概述
MyBatisPlus 提供了强大的插件机制,其中 `MybatisPlusInterceptor` 是核心组件之一。通过它,可以轻松实现诸如分页、多租户等功能[^1]。
为了同时支持分页和多租户功能,可以通过配置 `MybatisPlusInterceptor` 并注册多个子拦截器来完成需求。以下是具体实现方式:
---
#### 配置分页拦截器与租户拦截器
在 Spring Boot 项目中,通常会在启动类或者配置类中初始化并注册这些拦截器。以下是一个完整的示例代码:
```java
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 注册分页拦截器
PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
interceptor.addInnerInterceptor(paginationInterceptor);
// 注册多租户拦截器
TenantLineInnerInterceptor tenantLineInterceptor = new TenantLineInnerInterceptor(new CustomTenantHandler());
tenantLineInterceptor.setIgnoreTable(Arrays.asList("sys_user", "sys_role")); // 可选:忽略某些表的租户过滤
interceptor.addInnerInterceptor(tenantLineInterceptor);
return interceptor;
}
}
```
上述代码中:
- 使用 `PaginationInnerInterceptor` 来启用分页功能[^3]。
- 使用 `TenantLineInnerInterceptor` 来启用多租户功能,并传入自定义的租户处理器 `CustomTenantHandler`[^2]。
---
#### 自定义租户处理逻辑
多租户的核心在于动态注入 SQL 的 WHERE 子句中的租户条件。下面是一个简单的租户处理器实现:
```java
import com.baomidou.mybatisplus.core.handlers.TenantLineHandler;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import java.util.Collections;
public class CustomTenantHandler implements TenantLineHandler {
private static final String TENANT_ID_COLUMN_NAME = "tenant_id";
@Override
public Expression getTenantId(boolean where) {
// 返回当前线程绑定的租户 ID (假设存储在 ThreadLocal 中)
String currentTenantId = CurrentUserContext.getTenantId(); // 获取当前用户的租户ID
return new StringValue(currentTenantId);
}
@Override
public String getTenantIdColumn() {
return TENANT_ID_COLUMN_NAME; // 数据库中用于区分租户的字段名
}
@Override
public boolean openTENANT_LINE(String tableName) {
// 判断哪些表需要开启多租户模式
return !tableName.startsWith("sys_"); // sys_* 表不参与多租户过滤
}
}
```
此代码片段展示了如何通过 `getTenantId()` 方法获取当前租户 ID,并将其作为 SQL 查询的一部分自动附加到查询语句中。
---
#### 示例场景
假设有如下数据库表结构:
| 表名 | 字段 |
|------------|----------------|
| order_info | id, name, price, tenant_id |
当执行以下分页查询时:
```sql
SELECT * FROM order_info LIMIT 0, 10;
```
实际生成的 SQL 将变为:
```sql
SELECT * FROM order_info WHERE tenant_id = 'current_tenant' LIMIT 0, 10;
```
这表明分页和多租户功能已成功集成。
---
#### 注意事项
1. **版本兼容性**
确保使用的 MyBatisPlus 版本不低于 3.4.0,因为低版本可能缺少部分功能或存在 Bug。
2. **性能优化**
对于高并发场景,建议缓存租户信息以减少频繁调用开销。
3. **异常处理**
如果未设置租户 ID 或者租户 ID 不合法,则可能导致查询失败。因此需提前校验输入参数。
---
mybatisplus 3 分页PaginationInnerInterceptor
<think>好的,我需要帮助用户了解MyBatisPlus 3中的PaginationInnerInterceptor分页配置和使用方法。首先,我应该回顾用户提供的引用内容,特别是引用1、2和3中的信息。用户提到了分页插件的配置、测试代码以及依赖问题。
首先,配置分页拦截器是关键步骤。根据引用1,需要配置分页拦截器,这可能涉及在MyBatisPlus的配置类中添加拦截器Bean。引用3提到在3.5.9版本中可能需要添加额外的依赖,如mybatis-plus-jsqlparser,所以需要提醒用户检查依赖版本是否正确。
接下来是使用方法。用户提供的引用2中的测试代码展示了如何使用selectPage方法,传入Page对象和查询条件。需要解释Page对象的构造,比如当前页码和每页数量,以及如何处理查询结果的分页数据。
还需要考虑可能遇到的问题,比如分页不生效,这时候可能需要检查拦截器是否配置正确,或者依赖是否缺失。引用3中的解决方案可以在这里提及,确保用户知道如何处理类似问题。
另外,用户可能对自定义分页功能感兴趣,引用1提到了自定义分页,可能需要简要说明如何扩展分页功能,比如使用自定义的XML语句或Page对象的方法。
最后,生成相关问题时要覆盖配置、使用、常见问题以及高级功能,帮助用户深入理解。需要确保所有步骤清晰,代码示例正确,并且注意事项突出,避免用户在实际操作中遇到问题。</think>### MyBatisPlus 3 PaginationInnerInterceptor 分页配置及使用方法
#### 1. 配置分页拦截器
在MyBatisPlus中,需通过配置拦截器启用分页功能。在Spring Boot配置类中添加以下代码:
```java
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
```
需注意:
- 选择与数据库类型匹配的`DbType`参数(如`MYSQL`/`ORACLE`)
- 3.5.9版本需添加`mybatis-plus-jsqlparser`依赖[^3]
#### 2. 分页查询实现
在Mapper接口中使用`selectPage`方法:
```java
// Mapper接口定义
public interface UserMapper extends BaseMapper<User> {
// 继承自带分页方法
}
// 分页查询示例
Page<User> page = new Page<>(2, 3); // 第2页,每页3条
Page<User> result = userMapper.selectPage(page, null);
```
获取分页数据:
```java
List<User> records = result.getRecords(); // 当前页数据
long total = result.getTotal(); // 总记录数
long pages = result.getPages(); // 总页数
```
#### 3. 自定义分页查询
对于复杂SQL,可在XML映射文件中自定义分页查询:
```xml
<select id="selectCustomPage" resultType="User">
SELECT * FROM user WHERE age > #{param1}
</select>
```
对应Mapper接口:
```java
IPage<User> selectCustomPage(Page<User> page, @Param("age") Integer age);
```
#### 4. 注意事项
1. **依赖问题**:3.5.1+版本需单独引入`mybatis-plus-jsqlparser`依赖
```xml
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
```
2. **性能优化**:建议配合`Page`对象的`optimizeCountSql`属性使用
```java
Page<User> page = new Page<>(1, 10).setOptimizeCountSql(true);
```
3. **多租户支持**:分页插件会自动处理租户字段过滤
4. **溢出处理**:通过`overflow`属性控制页码超出时的行为
```java
page.setOverflow(false); // 超出总页数时返回空列表
```
[^1]: 最新版MybatisPlus的分页功能配置说明
[^2]: PaginationInnerInterceptor的测试用例参考
: 分页插件依赖问题解决方案
阅读全文
相关推荐











