当前位置: 首页 > wzjs >正文

科技 杭州 网站建设网店网络推广方案

科技 杭州 网站建设,网店网络推广方案,设计参考图网站,建站 赚钱什么是数据权限 数据权限是指系统根据用户的角色、职位或其他属性,控制用户能够访问的数据范围。与传统的功能权限(菜单、按钮权限)不同,数据权限关注的是数据行级别的访问控制。 常见的数据权限控制方式包括: 部门数…

什么是数据权限

数据权限是指系统根据用户的角色、职位或其他属性,控制用户能够访问的数据范围。与传统的功能权限(菜单、按钮权限)不同,数据权限关注的是数据行级别的访问控制。

常见的数据权限控制方式包括:

  • 部门数据权限:只能访问本部门数据

  • 个人数据权限:只能访问自己的数据

  • 自定义数据范围:通过特定规则限制数据访问

MyBatis-Plus实现数据权限的方案

实现完整例子

下面是一个完整的基于MyBatis-Plus和Spring Security的数据权限实现示例:

 1. 数据权限配置类

@Configuration
public class MybatisConfig {@Beanpublic ConfigurationCustomizer mybatisConfigurationCustomizer(){return configuration -> configuration.setObjectWrapperFactory(new MapWrapperFactory());}@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 1.添加数据权限插件interceptor.addInnerInterceptor(new DataPermissionInterceptor(new DataPressionConfig()));PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();// 分页插件paginationInnerInterceptor.setOptimizeJoin(false);paginationInnerInterceptor.setOverflow(true);paginationInnerInterceptor.setDbType(DbType.POSTGRE_SQL);interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;}
}

     2. 数据权限拦截器
    @Slf4j
    @Component
    public class DataPressionConfig implements DataPermissionHandler {@Overridepublic Expression getSqlSegment(Expression where, String mappedStatementId) {try {if(null==mappedStatementId){return null;}Class<?> mapperClazz = Class.forName(mappedStatementId.substring(0, mappedStatementId.lastIndexOf(".")));String methodName = mappedStatementId.substring(mappedStatementId.lastIndexOf(".") + 1);// 获取自身类中的所有方法,不包括继承。与访问权限无关Method[] methods = mapperClazz.getDeclaredMethods();for (Method method : methods) {DataScope dataScopeAnnotationMethod = method.getAnnotation(DataScope.class);if(null==dataScopeAnnotationMethod){continue;}//spring aoc里拿方法参数Parameter[] parameters= method.getParameters();if (parameters.length > 0) {log.info("方法参数:" +  dataScopeAnnotationMethod.oneselfScopeName() );}if (ObjectUtils.isEmpty(dataScopeAnnotationMethod) || !dataScopeAnnotationMethod.enabled()) {continue;}if (method.getName().equals(methodName) || (method.getName() + "_COUNT").equals(methodName) || (method.getName() + "_count").equals(methodName)) {return buildDataScopeByAnnotation(dataScopeAnnotationMethod,mappedStatementId);}}} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}/*** DataScope注解方式,拼装数据权限** @param dataScope* @return*/private Expression buildDataScopeByAnnotation(DataScope dataScope,String mapperId) {Map<String, Object> params = DataPermissionContext.getParams();if (params == null || params.isEmpty()) {return null;}Object areaCodes = params.get(mapperId);List<String> dataScopeDeptIds=  (List<String>) areaCodes;// 获取注解信息String tableAlias = dataScope.tableAlias();String areaCodes= dataScope.areaCodes();Expression expression = buildDataScopeExpression(tableAlias,   areaCodes, dataScopeDeptIds);return expression == null ? null : new Parenthesis(expression);}/*** 拼装数据权限** @param tableAlias        表别名* @param oneselfScopeName  本人限制范围的字段名称* @param dataScopeDeptIds  数据权限部门ID集合,去重* @return*/private Expression buildDataScopeExpression(String tableAlias,  String areaCodes, List<String> dataScopeDeptIds) {/*** 构造部门里行政区划 area_code 的in表达式。*/try {String sql=tableAlias + "." + areaCodes+" in (";for(String areaCode:dataScopeDeptIds){sql+="'"+areaCode+"',";}sql=sql.substring(0,sql.length()-1)+")";Expression selectExpression = CCJSqlParserUtil.parseCondExpression(sql, true);return selectExpression;} catch (JSQLParserException e) {throw new RuntimeException(e);}}}

    3. 存储spring aop切面拿到的数据

         

      public class DataPermissionContext {private static final ThreadLocal<Map<String, Object>> CONTEXT = new ThreadLocal<>();public static void setParams(Map<String, Object> params) {CONTEXT.set(params);}public static Map<String, Object> getParams() {return CONTEXT.get();}public static void clear() {CONTEXT.remove();}
      }

         4. 定义数据权限注解
        @Inherited
        @Target({ElementType.METHOD, ElementType.TYPE})
        @Retention(RetentionPolicy.RUNTIME)
        public @interface DataScope {/*** 是否生效,默认true-生效*/boolean enabled() default true;/*** 表别名*/String tableAlias() default "";/*** 本人限制范围的字段名称*/String areaCodes() default "area_code";}
        5. 实现AOP切面
        @Slf4j
        @Aspect
        @Component
        public class DataAspet {@Pointcut("@annotation(DataScope)")public void logPoinCut() {}@Before("logPoinCut()")public void saveSysLog(JoinPoint joinPoint) {//从切面织入点处通过反射机制获取织入点处的方法MethodSignature signature = (MethodSignature) joinPoint.getSignature();//获取切入点所在的方法Method method = signature.getMethod();DataScope scope = method.getAnnotation(DataScope.class);Map<String, Object> paramValues = new HashMap<>();Object[] args = joinPoint.getArgs();Parameter[] parameters = method.getParameters();if(null!=parameters&&parameters.length>0) {//添加到最后一个参数log.info("参数名称:{}",signature.getName()+":"+signature.getDeclaringTypeName());paramValues.put(signature.getDeclaringTypeName()+"."+signature.getName(), args[parameters.length-1]);DataPermissionContext.setParams(paramValues);}else{DataPermissionContext.setParams(null);}}}

        6. mapper里注解使用数据权限

        tableAlias里你的sql里面要插入数据权限字段的表别名。

        比如:

        select count(*) as total,d.type as type from bus_device d group by d.type

        spring aop 会读取mapper方法最后一个参数,然后切入Sql变成

        select count(*) as total,d.type as type from bus_device d where

        d.area_code in(#{areaCodes} )  group by d.type

            @DataScope(tableAlias = "d")List<DeviceTypeCountDto> listByApplicationCategory(@Param(  @Param("type") String type,List<String> areaCodes);
        

        注意事项

        1. 性能考虑:数据权限过滤会增加SQL复杂度,可能影响查询性能,特别是对于大数据量表。可以考虑添加适当的索引优化。

        2. SQL注入风险:在拼接SQL时要特别注意防止SQL注入,建议使用预编译参数。

        3. 缓存问题:如果使用了缓存,需要注意数据权限可能导致缓存命中率下降或数据泄露问题。

        4. 多租户场景:在多租户系统中,数据权限通常需要与租户隔离一起考虑。

        5. 复杂查询:对于复杂的多表关联查询,数据权限条件可能需要更精细的控制。

        通过以上方案,我们可以灵活地在MyBatis-Plus中实现各种数据权限控制需求,根据项目实际情况选择最适合的实现方式。

        http://www.dtcms.com/wzjs/5843.html

        相关文章:

      1. 最专业的外贸网站建设软文范例大全800
      2. 郑州网站建设做推广吗行者seo
      3. 网站后台发邮件站长工具官网查询
      4. 怎样做网站轮播万能搜索 引擎
      5. 做网站需要用到的符号语言内部搜索引擎优化
      6. 昆明网站建设推广安徽网络seo
      7. 茂名网站建设公司什么是软文推广
      8. 制作网站页面怎么做大批量刷关键词排名软件
      9. 做网站费用计入什么seo公司排名教程
      10. 做家常菜的网站深圳搜索引擎优化收费
      11. 做的网站怎样适配手机屏幕如何写市场调研报告
      12. 巩义网站建设全球访问量top100网站
      13. 网站建设大概好多钱百度搜索风云榜单
      14. 昆明找工作哪个网站好四川省人民政府
      15. php盗版视频网站怎么做的google play下载安装
      16. 做外贸企业网站要注意哪些微信搜一搜怎么做推广
      17. 网站开发百度百科营销顾问
      18. 做网站要不要学ps天津网络广告公司
      19. php 政府网站源码西安网站外包
      20. 如何做农产品网站杭州百度竞价推广公司
      21. 南上海网站建设网站怎样被百度收录
      22. 精品服装网站建设网页制作代码模板
      23. 政府单位网站建设方案百度霸屏推广
      24. 网站手机验证码如何做杭州seo关键字优化
      25. 开网站供免费下载长春seo公司哪家好
      26. 做网站的北京商铺营销推广方案
      27. 合肥市城乡建设局2019网站企业网站建设的目的
      28. 新疆网站建设一条龙服务线上推广有哪些平台效果好
      29. 网站怎样做没有病毒网推怎么做最有效
      30. 网站主机多少钱seo页面代码优化