一、添加依赖

   <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

 二、添加注解,用户判断是否是要数据权限

package com.tuling.dynamic.datasource.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataScope {
    /**
     * 是否启用
     */
    boolean enabled() default true;

    /**
     * 表别名
     */
    String tableAlias() default "";

    /**
     * 表字段
     */
    String tableField() default "user_id";

}

 三、配置一个mybatis拦截器对象

package com.tuling.dynamic.datasource.anno;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisConfigInterceptor {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        return new MybatisPlusInterceptor();
    }
}

 四、添加一个拦截器,并根据用户查询权限修改sql

package com.tuling.dynamic.datasource.anno;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.RequiredArgsConstructor;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.parser.Node;
import net.sf.jsqlparser.parser.SimpleNode;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.PlainSelect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

@Component
public class PermissionRunner implements ApplicationRunner {

    @Resource
    private MybatisPlusInterceptor mybatisPlusInterceptor;

    @Resource
    private PermissionHandling permissionHandling;


    @Override
    public void run(ApplicationArguments args) throws Exception {
        mybatisPlusInterceptor.addInnerInterceptor(new DataPermissionInterceptor(new InnerDataPermissionHandler(permissionHandling)));
    }

    @RequiredArgsConstructor
    public static class InnerDataPermissionHandler implements MultiDataPermissionHandler {

        private final PermissionHandling permissionHandling;

        @Override
        public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) {
            try {
                Class<?> mapperClazz = Class.forName(mappedStatementId.substring(0, mappedStatementId.lastIndexOf(".")));
                String methodName = mappedStatementId.substring(mappedStatementId.lastIndexOf(".") + 1);
                // 获取自身类中的所有方法,不包括继承。与访问权限无关
                Method[] methods = mapperClazz.getDeclaredMethods();
                if (methods.length == 0) {
                    return null;
                }
                Method targetMethods = Arrays.stream(methods).filter(method -> method.getName().equals(methodName)).findFirst().orElse(null);
                if (targetMethods == null) {
                    return null;
                }
                DataScope dataScopeAnnotationMethod = targetMethods.getAnnotation(DataScope.class);
                if (ObjectUtils.isEmpty(dataScopeAnnotationMethod) || !dataScopeAnnotationMethod.enabled()) {
                    return null;
                } else {
                    // 跳过join中的on条件表达式拼装
                    if (where != null && where.getASTNode() != null && where.getASTNode().jjtGetParent().jjtGetParent().toString().equals("JoinerExpression")) {
                        return null;
                    }
                    return buildDataScopeByAnnotation(dataScopeAnnotationMethod);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        /**
         * 根据注解构建express语句
         */
        private Expression buildDataScopeByAnnotation(DataScope dataScopeAnnotationMethod) {
            //可以判断是否是管理员,如果是管理员就是全部权限
            // 构建权限语句
            // 构造用户in表达式。
            Long currLoginUserId = 1L; //获取当前登录用户id
            InExpression userIdsInExpression = new InExpression();
            //获取当前用户能够管理的用户权限
            List<Long> userIds = permissionHandling.getUserIdsByUserId(currLoginUserId);
            // 权限适用范围为全部
            if (userIds == null) {
                return null;
            }
            if (userIds.isEmpty()) {
                throw new RuntimeException("当前权限适用范围内暂无用户数据筛选");
            }
            ExpressionList expressionList = new ExpressionList();
            userIds.forEach(a -> expressionList.addExpressions(new StringValue(a.toString())));
            // 设置左边的字段表达式,右边设置值。
            userIdsInExpression.setLeftExpression(buildColumn(dataScopeAnnotationMethod.tableAlias(), dataScopeAnnotationMethod.tableField()));
            userIdsInExpression.setRightItemsList(expressionList);
            return userIdsInExpression;
        }

        /**
         * 构建Column
         *
         * @param tableAlias 表别名
         * @param columnName 字段名称
         * @return 带表别名字段
         */
        private Column buildColumn(String tableAlias, String columnName) {
            if (StringUtils.isNotEmpty(tableAlias)) {
                columnName = tableAlias + "." + columnName;
            }
            return new Column(columnName);
        }

    }

}

 五、权限查询接口

package com.tuling.dynamic.datasource.anno;

import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class PermissionHandling {
    /**
     * 根据用户Id获取权限范围的用户Id
     *
     * @param userId 用户Id
     * @return {@link List}<{@link String}>
     */
    List<Long> getUserIdsByUserId(Long userId){
        return List.of(1L,2L,3L);
    }
}