首页
/ MyBatis-Plus数据权限拦截器实现多条件IN查询过滤

MyBatis-Plus数据权限拦截器实现多条件IN查询过滤

2025-05-14 12:49:55作者:伍希望

数据权限拦截器概述

MyBatis-Plus的数据权限拦截器(DataPermissionInterceptor)是一个强大的功能组件,它允许开发者在SQL执行前动态添加数据过滤条件,实现行级数据权限控制。在实际业务场景中,我们经常需要根据用户的权限范围,对查询结果进行过滤,例如只允许用户查看自己所属部门或特定仓库的数据。

多条件IN查询的需求

在实际开发中,我们经常会遇到需要同时基于多个字段进行IN查询过滤的场景。例如:

  • 只允许用户查看特定仓库(WHSEID)的数据
  • 同时限制用户只能查看特定货主(STORER_KEY)的数据
  • 可能还有其他需要过滤的条件

理想情况下,我们希望生成的SQL类似于:

SELECT * FROM table 
WHERE whseid IN (仓库ID列表) 
AND storer_key IN (货主列表)
AND 其他条件...

实现方案分析

1. 继承DataPermissionHandler

MyBatis-Plus提供了DataPermissionHandler接口,我们可以通过实现这个接口来自定义数据权限过滤逻辑。核心方法是getSqlSegment,它返回需要添加到SQL中的条件片段。

2. 构建复合条件表达式

在实现中,我们需要构建一个包含多个IN条件的复合表达式。MyBatis-Plus内部使用JSqlParser来解析和修改SQL,因此我们可以利用其提供的表达式类来构建复杂的条件。

3. 正确的表达式组合方式

在原始问题中,用户尝试使用AndExpression来组合多个InExpression,但写法存在问题。正确的做法应该是:

  1. 创建第一个IN条件表达式
  2. 创建第二个IN条件表达式
  3. 使用AndExpression将两个条件连接起来
  4. 如果有更多条件,继续用AndExpression连接

完整实现示例

public class MultiInDataPermissionHandler implements DataPermissionHandler {
    
    @Override
    public Expression getSqlSegment(Expression where, String mappedStatementId) {
        // 获取当前用户的权限范围数据
        List<String> whseids = getCurrentUserWhseids();
        List<String> storerKeys = getCurrentUserStorerKeys();
        
        // 构建第一个IN条件
        InExpression whseidInExpression = new InExpression(
            new Column("whseid"), 
            new ExpressionList(whseids.stream()
                .map(StringValue::new)
                .collect(Collectors.toList()))
        );
        
        // 构建第二个IN条件
        InExpression storerKeyInExpression = new InExpression(
            new Column("storer_key"), 
            new ExpressionList(storerKeys.stream()
                .map(StringValue::new)
                .collect(Collectors.toList()))
        );
        
        // 组合条件
        AndExpression combinedExpression = new AndExpression(whseidInExpression, storerKeyInExpression);
        
        // 如果原有WHERE条件不为空,需要与新条件组合
        if (where != null) {
            return new AndExpression(where, combinedExpression);
        }
        
        return combinedExpression;
    }
    
    private List<String> getCurrentUserWhseids() {
        // 实现获取当前用户有权限的仓库ID列表
    }
    
    private List<String> getCurrentUserStorerKeys() {
        // 实现获取当前用户有权限的货主列表
    }
}

注意事项

  1. 表达式构建顺序:确保按照正确的逻辑顺序构建表达式,避免条件冲突
  2. 空值处理:当权限列表为空时,应考虑是否返回所有数据或无数据
  3. 性能考虑:IN列表过长可能影响查询性能,应考虑分批或其他优化方式
  4. SQL注入防护:确保所有动态值都经过适当的处理,防止SQL注入

扩展应用

这种多条件IN查询过滤不仅适用于数据权限控制,还可以应用于:

  1. 多租户系统的数据隔离
  2. 多组织架构的数据权限管理
  3. 复杂的业务数据过滤场景
  4. 动态查询条件构建

通过灵活运用MyBatis-Plus的数据权限拦截器,我们可以实现高度可定制化的数据访问控制,满足各种复杂的业务需求。

登录后查看全文
热门项目推荐
相关项目推荐