基于aop注解形式和 mybatis-plus3.4.2实现数据权限控制

本文介绍了如何结合AOP注解和Mybatis-Plus 3.4.2版本来实现数据权限控制。通过ThreadLocal管理是否启用权限,启用时利用Mybatis-Plus的DataPermissionHandler进行处理。详细步骤包括:定义控制器上的DataScope注解、实现AOP切面DataScopeAspect、创建ThreadLocal实现类DataScopeContext、设计数据权限插件HkhjDataPermissionHandler、配置MybatisPlusConfig加载插件,以及在Controller层应用注解。
摘要由CSDN通过智能技术生成

1、实现思路,通过ThreadLocal获取是否开启数据权限,开启则通过mybatis-plus的DataPermissionHandler实现数据权限

controller上添加的注解DataScope.java

package com.pojo.common.datascope.annotation;

import com.pojo.common.core.config.HkhjDataPermissionHandler;
import com.pojo.common.core.utils.DataScopeContext;

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

/**
 * 数据权限过滤注解
 *
 * @author zsj
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope {
    /**
     * 部门数据权限查询列名
     */
    String deptId() default DataScopeContext.DEPT_ID;

    /**
     * 用户数据权限查询列名
     */
    String userSelf() default DataScopeContext.USER_SELF;
}

2、aop切面DataScopeAspect.java

package com.pojo.common.datascope.aspect;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.pojo.common.core.config.HkhjDataPermissionHandler;
import com.pojo.common.core.utils.DataScopeContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.pojo.common.datascope.annotation.DataScope;
import com.pojo.common.security.service.TokenService;
import com.pojo.system.api.domain.SysUser;
import com.pojo.system.api.model.LoginUser;

/**
 * 数据过滤处理
 *
 * @author ruoyi
 */
@Aspect
@Component
public class DataScopeAspect {


    @Autowired
    private TokenService tokenService;


    // 配置织入点
    @Pointcut("@annotation(com.pojo.common.datascope.annotation.DataScope)")
    public void dataScopePointCut() {
    }

    @Before("dataScopePointCut()")
    public void doBefore(JoinPoint point) throws Throwable {
        handleDataScope(point);
    }

    protected void handleDataScope(final JoinPoint joinPoint) {
        // 获得注解
        DataScope controllerDataScope = getAnnotationLog(joinPoint);
        Map<String, String> map = Maps.newConcurrentMap();
        if (controllerDataScope == null) {
            map.put(DataScopeContext.OPEN_DATA_SCOPE, "false");
            DataScopeContext.setContextMap(map);
            return;
        }
        // 获取当前的用户
        LoginUser loginUser = tokenService.getLoginUser();
        if (Objects.nonNull(loginUser)) {
            SysUser currentUser = loginUser.getSysUser();
            Map<String, String> dataScopeFilter = dataScopeFilter(currentUser);
            map.put(DataScopeContext.OPEN_DATA_SCOPE, "true");
            map.put(DataScopeContext.DEPT_ID, controllerDataScope.deptId());
            map.put(DataScopeContext.USER_SELF, controllerDataScope.userSelf());
            map.put(DataScopeContext.USER_NAME, currentUser.getUserName());
            map.put(DataScopeContext.DATA_SCOPE_DEPT_ID, dataScopeFilter.getOrDefault(DataScopeContext.DATA_SCOPE_DEPT_ID, "-1"));
            map.put(DataScopeContext.DATA_SCOPE, dataScopeFilter.get(DataScopeContext.DATA_SCOPE));
            DataScopeContext.setContextMap(map);
        }

    }

    /**
     * 数据范围过滤
     *
     * @param user 用户
     */
    public static Map<String, String> dataScopeFilter(SysUser user) {
        Set<String> dataScope = Sets.newHashSet();
        Map<String, String> result 
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SpringBoot是一个高效的Java开发框架,它能够方便开发者集成MyBatis-Plus实现数据源的动态切换以及支持分页查询。MyBatis-Plus是一种优秀的ORM框架,它增强了MyBatis的基础功能,并支持通过注解方式进行映射。 首先,我们需要在pom.xml文件中添加MyBatis-Plus数据库连接池的依赖。在application.yml文件中,我们需要配置多个数据源和对应的连接信息。我们可以定义一个DataSourceConfig用于获取多个数据源,然后在Mapper配置类中使用@MapperScan(basePackages = {"com.test.mapper"})来扫描Mapper接口。 要实现动态切换数据源,我们可以自定义一个注解@DataSource来标注Mapper接口或方法,然后使用AOP拦截数据源切换,实现动态切换。在实现分页查询时,我们可以使用MyBatis-Plus提供的分页插件来支持分页查询。 代码示例: 1. 在pom.xml文件中添加MyBatis-Plus数据库连接池的依赖。 ``` <dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.4</version> </dependency> </dependencies> ``` 2. 在application.yml文件中配置多个数据源和对应的连接信息。以两个数据源为例: ``` spring: datasource: druid: db1: url: jdbc:mysql://localhost:3306/db1 username: root password: root driver-class-name: com.mysql.jdbc.Driver db2: url: jdbc:mysql://localhost:3306/db2 username: root password: root driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource # 指定默认数据源 primary: db1 ``` 3. 定义一个DataSourceConfig用于获取多个数据源。 ``` @Configuration public class DataSourceConfig { @Bean("db1") @ConfigurationProperties("spring.datasource.druid.db1") public DataSource dataSource1() { return DruidDataSourceBuilder.create().build(); } @Bean("db2") @ConfigurationProperties("spring.datasource.druid.db2") public DataSource dataSource2() { return DruidDataSourceBuilder.create().build(); } @Bean @Primary public DataSource dataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); // 设置数据源映射关系 Map<Object, Object> dataSourceMap = new HashMap<>(); dataSourceMap.put("db1", dataSource1()); dataSourceMap.put("db2", dataSource2()); dynamicDataSource.setTargetDataSources(dataSourceMap); // 设置默认数据源 dynamicDataSource.setDefaultTargetDataSource(dataSource1()); return dynamicDataSource; } } ``` 4. 在Mapper配置类中使用@MapperScan(basePackages = {"com.test.mapper"})来扫描Mapper接口,并使用@DataSource注解来标注Mapper接口或方法。 ``` @Configuration @MapperScan(basePackages = {"com.test.mapper"}) public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } } @DataSource("db1") public interface UserMapper { @Select("select * from user where id = #{id}") User selectById(@Param("id") Long id); } ``` 5. 实现AOP拦截数据源切换。 ``` @Aspect @Component public class DataSourceAspect { @Before("@annotation(ds)") public void beforeSwitchDataSource(JoinPoint point, DataSource ds) { String dataSource = ds.value(); if (!DynamicDataSourceContextHolder.containDataSourceKey(dataSource)) { System.err.println("数据源 " + dataSource + " 不存在,使用默认数据源"); } else { System.out.println("使用数据源:" + dataSource); DynamicDataSourceContextHolder.setDataSourceKey(dataSource); } } } ``` 6. 分页查询的使用示例: ``` @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override @DataSource("db1") public IPage<User> getUserList(int pageNum, int pageSize) { Page<User> page = new Page<>(pageNum, pageSize); return userMapper.selectPage(page, null); } } ``` 以上就是SpringBoot整合MyBatis-Plus实现数据源的动态切换和分页查询的具体实现过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非ban必选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值