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

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

2025-05-14 20:35:44作者:伍希望

数据权限拦截器概述

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的数据权限拦截器,我们可以实现高度可定制化的数据访问控制,满足各种复杂的业务需求。

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

热门内容推荐

最新内容推荐

项目优选

收起
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
176
262
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
863
511
ShopXO开源商城ShopXO开源商城
🔥🔥🔥ShopXO企业级免费开源商城系统,可视化DIY拖拽装修、包含PC、H5、多端小程序(微信+支付宝+百度+头条&抖音+QQ+快手)、APP、多仓库、多商户、多门店、IM客服、进销存,遵循MIT开源协议发布、基于ThinkPHP8框架研发
JavaScript
93
15
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
129
182
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
259
300
kernelkernel
deepin linux kernel
C
22
5
cherry-studiocherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
TypeScript
596
57
CangjieCommunityCangjieCommunity
为仓颉编程语言开发者打造活跃、开放、高质量的社区环境
Markdown
1.07 K
0
HarmonyOS-ExamplesHarmonyOS-Examples
本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计!
Cangjie
398
371
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
332
1.08 K