MybatisPlus實現(xiàn)數(shù)據(jù)攔截的使用示例
基于配置文件實現(xiàn)(關(guān)鍵key存儲在配置文件,通過讀取配置文件來實現(xiàn)動態(tài)拼接sql)
1、創(chuàng)建注解類
@UserDataPermission(id="app")
注:id用以區(qū)分是小程序還是應(yīng)用程序
注解加的位置:
2、配置枚舉類配置文件 EDataPermissionType
3、創(chuàng)建攔截器重寫InnerInterceptor接口,重寫查詢方法
/** * 攔截器 */ @Data @NoArgsConstructor @AllArgsConstructor @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class MyDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor { /** * 數(shù)據(jù)權(quán)限處理器 */ 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)); } } /** * 設(shè)置 where 條件 * * @param plainSelect 查詢對象 * @param whereSegment 查詢條件片段 */ private void setWhere(PlainSelect plainSelect, String whereSegment) { Expression sqlSegment = this.dataPermissionHandler.getSqlSegment(plainSelect, whereSegment); if (null != sqlSegment) { plainSelect.setWhere(sqlSegment); } } }
4、創(chuàng)建處理類,動態(tài)拼接sql片段,設(shè)置where
/** * 攔截器處理器 */ @Slf4j public class MyDataPermissionHandler { private ISysUserDataRelationService sysUserDataRelationService = new SysUserDataRelationServiceImpl(); private MpcTokenUtil mpcTokenUtil = new MpcTokenUtil(); private AppManageConfig appManageConfig; /** * 獲取數(shù)據(jù)權(quán)限 SQL 片段 * * @param plainSelect 查詢對象 * @param whereSegment 查詢條件片段 * @return JSqlParser 條件表達(dá)式 */ @SneakyThrows(Exception.class) public Expression getSqlSegment(PlainSelect plainSelect, String whereSegment) { sysUserDataRelationService = SpringUtils.getBean(ISysUserDataRelationService.class); mpcTokenUtil = SpringUtils.getBean(MpcTokenUtil.class); appManageConfig = SpringUtils.getBean(AppManageConfig.class); // 待執(zhí)行 SQL Where 條件表達(dá)式 Expression where = plainSelect.getWhere(); if (where == null) { where = new HexValue(" 1 = 1 "); } //獲取mapper名稱 String className = whereSegment.substring(0, whereSegment.lastIndexOf(".")); //獲取方法名 String methodName = whereSegment.substring(whereSegment.lastIndexOf(".") + 1); Table fromItem = (Table) plainSelect.getFromItem(); // 有別名用別名,無別名用表名,防止字段沖突報錯 Alias fromItemAlias = fromItem.getAlias(); String mainTableName = fromItemAlias == null ? fromItem.getName() : fromItemAlias.getName(); //獲取當(dāng)前mapper 的方法 Method[] methods = Class.forName(className).getMethods(); //遍歷判斷mapper 的所有方法,判斷方法上是否有 UserDataPermission for (Method m : methods) { if (Objects.equals(m.getName(), methodName)) { UserDataPermission annotation = m.getAnnotation(UserDataPermission.class); if (annotation == null) { return where; } String type = annotation.id(); //小程序或應(yīng)用程序的集合,in的范圍 List<String> dataIds = sysUserDataRelationService.getUserPermission(mpcTokenUtil.getUserAccountByToken(), EDataPermissionType.getCode(type)); if (CollectionUtils.isEmpty(dataIds)) { return null; } log.info("開始進(jìn)行權(quán)限過濾,where: {},mappedStatementId: {}", where, whereSegment); // 把集合轉(zhuǎn)變?yōu)镴SQLParser需要的元素列表 ItemsList ids = new ExpressionList(dataIds.stream().map(StringValue::new).collect(Collectors.toList())); //in表達(dá)式的寫法 InExpression inExpressiondept = null; String key = appManageConfig.getList().get(type); inExpressiondept = new InExpression(new Column(mainTableName + "." + key), ids); return new AndExpression(where, inExpressiondept); } } //說明無權(quán)查看, where = new HexValue(" 1 = 2 "); return where; } }
5、將攔截器加到mybatis-plus插件中
@Configuration @MapperScan("com.shinho.mpc.mapper") public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } /** * 將攔截器加到mybatis插件中 * @return */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加數(shù)據(jù)權(quán)限插件 MyDataPermissionInterceptor dataPermissionInterceptor = new MyDataPermissionInterceptor(); // 添加自定義的數(shù)據(jù)權(quán)限處理器 dataPermissionInterceptor.setDataPermissionHandler(new MyDataPermissionHandler()); interceptor.addInnerInterceptor(dataPermissionInterceptor); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }
6、使用的位置加注解即可生效
在mapper層加上注解:
@UserDataPermission(id="app")
- id :注解入?yún)?/li>
- app:應(yīng)用程序類型權(quán)限控制
- mp:小程序類型權(quán)限控制
7、數(shù)據(jù)攔截效果:
到此這篇關(guān)于MybatisPlus實現(xiàn)數(shù)據(jù)攔截的使用示例的文章就介紹到這了,更多相關(guān)MybatisPlus 數(shù)據(jù)攔截 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java集合框架 arrayblockingqueue應(yīng)用分析
ArrayBlockingQueue是一個由數(shù)組支持的有界阻塞隊列。此隊列按 FIFO(先進(jìn)先出)原則對元素進(jìn)行排序。隊列的頭部 是在隊列中存在時間最長的元素2012-11-11Spring事務(wù)中的事務(wù)傳播行為使用方式詳解
Spring框架作為一個輕量級的開源框架,在企業(yè)應(yīng)用開發(fā)中被廣泛使用,在Spring事務(wù)管理中,事務(wù)傳播行為是非常重要的一部分,它定義了方法如何參與到已經(jīng)存在的事務(wù)中或者如何開啟新的事務(wù),本文將詳細(xì)介紹Spring事務(wù)中的幾種事務(wù)傳播行為,詳細(xì)講解具體使用方法2023-06-06MybatisPlus實現(xiàn)分頁效果并解決錯誤問題:cant?found?IPage?for?args
這篇文章主要介紹了MybatisPlus實現(xiàn)分頁效果并解決錯誤:cant?found?IPage?for?args,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02快速學(xué)會Dubbo的配置環(huán)境及相關(guān)配置
本文主要講解Dubbo的環(huán)境與配置,文中運用大量代碼和圖片講解的非常詳細(xì),需要學(xué)習(xí)或用到相關(guān)知識的小伙伴可以參考這篇文章2021-09-09Java拷貝數(shù)組方法Arrays.copyOf()是地址傳遞的證明實例
今天小編就為大家分享一篇關(guān)于Java拷貝數(shù)組方法Arrays.copyOf()是地址傳遞的證明實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10Java使用JDK與Cglib動態(tài)代理技術(shù)統(tǒng)一管理日志記錄
這篇文章主要介紹了Java使用JDK與Cglib動態(tài)代理技術(shù)統(tǒng)一管理日志記錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05解決myBatis中openSession()自動提交的問題
在學(xué)習(xí)MySQL過程中,發(fā)現(xiàn)插入操作自動提交,問題原因可能是myBatis中的openSession()方法設(shè)置了自動提交,或者是MySQL的默認(rèn)引擎設(shè)置為不支持事務(wù)的MyISAM,解決辦法包括更改myBatis的提交設(shè)置或?qū)ySQL表的引擎改為InnoDB2024-09-09java小知識之查詢數(shù)據(jù)庫數(shù)據(jù)的元信息
這篇文章主要給大家介紹了關(guān)于java小知識之查詢數(shù)據(jù)庫數(shù)據(jù)的元信息,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2021-10-10