工作小总结&小工具类

利用 MyBatis Plus 拦截器动态管理数据访问权限

利用MyBatisPlus拦截器动态管理数据访问权限引言功能权限与数据权限在软件开发过程中,我们经常遇到需要根据用户角色来控制数据访问权限的需求。特别是在列表数据展示时,要确保用户只能查看其权限数据范围内的。本文将介绍一种通过MyBatis拦截器实现数据权限控制的方案,该方案灵活且易于集成到现有项目中。数据权限分配01基础版本实现1.创建注解类首先,我们需要创建一个自定义注解@UserDataPe

利用 MyBatis Plus 拦截器动态管理数据访问权限


引言

d7b27f9467b1ebe6a33a809a2c817f8e.png

功能权限与数据权限


在软件开发过程中,我们经常遇到需要根据用户角色来控制数据访问权限的需求。特别是在列表数据展示时,要确保用户只能查看其权限数据范围内的。本文将介绍一种通过MyBatis拦截器实现数据权限控制的方案,该方案灵活且易于集成到现有项目中。

33b4644bf0337c9be643ab337bfe00cb.png

数据权限分配

01基础版本实现
1. 创建注解类
首先,我们需要创建一个自定义注解 @UserDataPermission,用于标记需要进行数据权限控制的方法或类。具体代码如下:


import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;


@Target({ ElementType.METHOD, ElementType.TYPE })

@Retention(RetentionPolicy.RUNTIME)

public @interface UserDataPermission {

}


2. 创建拦截器
接下来,创建一个拦截器 MyDataPermissionInterceptor,实现 InnerInterceptor 接口,并重写查询方法。代码如下:


import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;

import com.baomidou.mybatisplus.core.toolkit.PluginUtils;

import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;

import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;

import lombok.Data;

import lombok.NoArgsConstructor;

import lombok.ToString;

import lombok.EqualsAndHashCode;

import net.sf.jsqlparser.expression.Expression;

import net.sf.jsqlparser.statement.select.PlainSelect;

import net.sf.jsqlparser.statement.select.Select;

import net.sf.jsqlparser.statement.select.SelectBody;

import net.sf.jsqlparser.statement.select.SetOperationList;

import org.apache.ibatis.executor.Executor;

import org.apache.ibatis.mapping.BoundSql;

import org.apache.ibatis.mapping.MappedStatement;

import org.apache.ibatis.session.ResultHandler;

import org.apache.ibatis.session.RowBounds;

import java.sql.SQLException;

import java.util.List;


@Data

@NoArgsConstructor

@ToString(callSuper = true)

@EqualsAndHashCode(callSuper = true)

public class MyDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {

    private MyDataPermissionHandler dataPermissionHandler;


    @Override

    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {

        if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {

            return;

        }

        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);

        mpBs.sql(this.parserSingle(mpBs.sql(), ms.getId()));

    }


    @Override

    protected void processSelect(Select select, int index, String sql, Object obj) {

        SelectBody selectBody = select.getSelectBody();

        if (selectBody instanceof PlainSelect) {

            this.setWhere((PlainSelect) selectBody, (String) obj);

        } else if (selectBody instanceof SetOperationList) {

            SetOperationList setOperationList = (SetOperationList) selectBody;

            List<SelectBody> selectBodyList = setOperationList.getSelects();

            selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj));

        }

    }


    private void setWhere(PlainSelect plainSelect, String whereSegment) {

        Expression sqlSegment = this.dataPermissionHandler.getSqlSegment(plainSelect, whereSegment);

        if (sqlSegment != null) {

            plainSelect.setWhere(sqlSegment);

        }

    }

}


3. 创建处理类
创建一个处理类 MyDataPermissionHandler,用于生成数据权限的 SQL 片段。如下代码:


import lombok.SneakyThrows;

import lombok.extern.slf4j.Slf4j;

import net.sf.jsqlparser.expression.Expression;

import net.sf.jsqlparser.expression.HexValue;

import net.sf.jsqlparser.expression.operators.relational.EqualsTo;

import net.sf.jsqlparser.schema.Column;

import net.sf.jsqlparser.schema.Tab

原创不易,完成人机校验,阅读全文

相关推荐