日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据权限实现

發布時間:2024/9/27 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据权限实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

權限框架可以根據用戶所屬角色決定有權限看到的菜單資源權限。
同一個資源下的同一個菜單的數據權限需要單獨處理。

案例:一部門的張三和二部門的李四都是普通用戶角色,普通用戶都有用戶管理的查詢權限,但是,一部門的張三只能看到一部門以及一部門下面的數據的權限。

效果圖:
測試部門的test001用戶之后能看到自己部門的數據,需求部門的數據看不到

文章目錄

          • 一、數據權限模型
            • 1. 實現原理
            • 2. 實現流程
            • 3. 權限標識對象
            • 4. 查詢SQL攔截器
            • 5. 查詢SQL特殊處理
          • 二、數據權限使用
            • 2.1. 控制層
            • 2.2. service
            • 2.3. mapper
            • 2.4. 獲取部門集合
            • 2.5.
          • 三、實戰演練
            • 3.1. 獲取當前用戶的所屬部門
            • 3.2. 獲取當前用戶的所屬部門以及子部門集合
            • 3.3. 調用邏輯service層執行查詢邏輯
            • 3.4. 調用mapper執行查詢邏輯
            • 3.5. 在查詢數據庫之前攔截處理
            • 3.6. 未處理的原sql
            • 3.7. 處理后的sql

一、數據權限模型
1. 實現原理
1.創建一個需要執行數據權限的標志 2.根據數據權限標識對原查詢SQL,在查詢數據庫之前進行特殊處理 3.利用攔截器在使用mapper在查詢數據庫時進行攔截處理1>獲取所有的查詢SQL2>獲取查詢sql中的的數據權限標識無:放行有:動態拼接數據權限sql
2. 實現流程
1.創建一個需要執行數據權限的標志對象DataScope 2.除超級管理員外,進行數據權限處理 3.獲取當前用戶的所處部門ID,根據部門ID獲取當前部門以及子部門的ID集合 4.創建數據范圍的攔截器DataScopeInterceptor 5.再判斷根據數據權限標識對原查詢SQL,利用攔截器在使用mapper在查詢數據庫時進行攔截處理1>獲取所有的查詢SQL2>獲取查詢sql中的的數據權限標識無:放行有:動態拼接數據權限sql簡言之:將源sql看做一個查詢整體,最后將結果集按照部門ids集合進行模糊區配篩選出(當前部門以及子部門的權限范圍)
3. 權限標識對象
package cn.stylefeng.roses.core.datascope;import java.util.List;/*** 數據范圍** @author fengshuonan* @date 2017-07-23 22:19*/ public class DataScope {/*** 限制范圍的字段名稱*/private String scopeName = "deptid";/*** 具體的數據范圍*/private List<Long> deptIds;public DataScope() {}public DataScope(List<Long> deptIds) {this.deptIds = deptIds;}public DataScope(String scopeName, List<Long> deptIds) {this.scopeName = scopeName;this.deptIds = deptIds;}public List<Long> getDeptIds() {return deptIds;}public void setDeptIds(List<Long> deptIds) {this.deptIds = deptIds;}public String getScopeName() {return scopeName;}public void setScopeName(String scopeName) {this.scopeName = scopeName;} }
4. 查詢SQL攔截器
5. 查詢SQL特殊處理
package cn.stylefeng.roses.core.datascope;import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.toolkit.PluginUtils; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlCommandType; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject;import java.sql.Connection; import java.util.List; import java.util.Map; import java.util.Properties;/*** 數據范圍的攔截器** @author fengshuonan* @date 2017-07-23 21:26*/ @Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}) public class DataScopeInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {return invocation.proceed();}BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");String originalSql = boundSql.getSql();Object parameterObject = boundSql.getParameterObject();//查找參數中包含DataScope類型的參數DataScope dataScope = findDataScopeObject(parameterObject);if (dataScope == null) {return invocation.proceed();} else {String scopeName = dataScope.getScopeName();List<Long> deptIds = dataScope.getDeptIds();String join = CollectionUtil.join(deptIds, ",");originalSql = "select * from (" + originalSql + ") temp_data_scope where temp_data_scope." + scopeName + " in (" + join + ")";metaStatementHandler.setValue("delegate.boundSql.sql", originalSql);return invocation.proceed();}}/*** 查找參數是否包括DataScope對象*/public DataScope findDataScopeObject(Object parameterObj) {if (parameterObj instanceof DataScope) {return (DataScope) parameterObj;} else if (parameterObj instanceof Map) {for (Object val : ((Map<?, ?>) parameterObj).values()) {if (val instanceof DataScope) {return (DataScope) val;}}}return null;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {} }
二、數據權限使用
2.1. 控制層
/*** 查詢管理員列表** @author gblfy* @Date 2020/12/24 22:43*/@RequestMapping("/list")@Permission@ResponseBodypublic Object list(@RequestParam(required = false) String name,@RequestParam(required = false) String timeLimit,@RequestParam(required = false) Long deptId) {//拼接查詢條件String beginTime = "";String endTime = "";if (ToolUtil.isNotEmpty(timeLimit)) {String[] split = timeLimit.split(" - ");beginTime = split[0];endTime = split[1];}if (ShiroKit.isAdmin()) {Page<Map<String, Object>> users = userService.selectUsers(null, name, beginTime, endTime, deptId);Page wrapped = new UserWrapper(users).wrap();return LayuiPageFactory.createPageInfo(wrapped);} else {DataScope dataScope = new DataScope(ShiroKit.getDeptDataScope());Page<Map<String, Object>> users = userService.selectUsers(dataScope, name, beginTime, endTime, deptId);Page wrapped = new UserWrapper(users).wrap();return LayuiPageFactory.createPageInfo(wrapped);}}
2.2. service
/*** 根據條件查詢用戶列表** @author gblfy* @Date 2020/12/24 22:45*/public Page<Map<String, Object>> selectUsers(DataScope dataScope, String name, String beginTime, String endTime, Long deptId) {Page page = LayuiPageFactory.defaultPage();return this.baseMapper.selectUsers(page, dataScope, name, beginTime, endTime, deptId);}
2.3. mapper
/*** 根據條件查詢用戶列表*/Page<Map<String, Object>> selectUsers(@Param("page") Page page, @Param("dataScope") DataScope dataScope, @Param("name") String name, @Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("deptId") Long deptId); <select id="selectUsers" resultType="map">select<include refid="Base_Column_List"/>from sys_userwhere status != 'DELETED'<if test="name != null and name != ''">and (phone like CONCAT('%',#{name},'%')or account like CONCAT('%',#{name},'%')or name like CONCAT('%',#{name},'%'))</if><if test="deptId != null and deptId != 0">and (dept_id = #{deptId} or dept_id in ( select dept_id from sys_dept where pids like CONCAT('%$[', #{deptId}, '$]%') escape '$' ))</if><if test="beginTime != null and beginTime != '' and endTime != null and endTime != ''">and (create_time between CONCAT(#{beginTime},' 00:00:00') and CONCAT(#{endTime},' 23:59:59'))</if></select>
2.4. 獲取部門集合
/*** 獲取當前用戶的部門數據范圍的集合*/public static List<Long> getDeptDataScope() {Long deptId = getUser().getDeptId();List<Long> subDeptIds = ConstantFactory.me().getSubDeptId(deptId);subDeptIds.add(deptId);return subDeptIds;}/*** 獲取子部門id*/@Overridepublic List<Long> getSubDeptId(Long deptId) {ArrayList<Long> deptIds = new ArrayList<>();if (deptId == null) {return deptIds;} else {List<Dept> depts = this.deptMapper.likePids(deptId);if (depts != null && depts.size() > 0) {for (Dept dept : depts) {deptIds.add(dept.getDeptId());}}return deptIds;}}
2.5.
三、實戰演練
3.1. 獲取當前用戶的所屬部門

3.2. 獲取當前用戶的所屬部門以及子部門集合


3.3. 調用邏輯service層執行查詢邏輯

3.4. 調用mapper執行查詢邏輯

3.5. 在查詢數據庫之前攔截處理

3.6. 未處理的原sql
selectuser_id AS "userId", avatar AS "avatar", account AS "account", salt AS "salt", name AS "name", birthday AS "birthday", sex AS "sex", email AS "email", phone AS "phone", role_id AS "roleId", dept_id AS "deptId", status AS "status", create_time AS "createTime", create_user AS "createUser", update_time AS "updateTime", update_user AS "updateUser", version AS "version"from sys_userwhere status != 'DELETED'
3.7. 處理后的sql
select * from (selectuser_id AS "userId", avatar AS "avatar", account AS "account", salt AS "salt", name AS "name", birthday AS "birthday", sex AS "sex", email AS "email", phone AS "phone", role_id AS "roleId", dept_id AS "deptId", status AS "status", create_time AS "createTime", create_user AS "createUser", update_time AS "updateTime", update_user AS "updateUser", version AS "version"from sys_userwhere status != 'DELETED') temp_data_scope where temp_data_scope.deptid in (26)

總結

以上是生活随笔為你收集整理的数据权限实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。