MybatisPlus實(shí)現(xiàn)數(shù)據(jù)攔截的使用示例
基于配置文件實(shí)現(xiàn)(關(guān)鍵key存儲(chǔ)在配置文件,通過(guò)讀取配置文件來(lái)實(shí)現(xiàn)動(dòng)態(tài)拼接sql)
1、創(chuàng)建注解類(lèi)
@UserDataPermission(id="app")
注:id用以區(qū)分是小程序還是應(yīng)用程序
注解加的位置:

2、配置枚舉類(lèi)配置文件 EDataPermissionType

3、創(chuàng)建攔截器重寫(xiě)InnerInterceptor接口,重寫(xiě)查詢(xún)方法
/**
* 攔截器
*/
@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 查詢(xún)對(duì)象
* @param whereSegment 查詢(xún)條件片段
*/
private void setWhere(PlainSelect plainSelect, String whereSegment) {
Expression sqlSegment = this.dataPermissionHandler.getSqlSegment(plainSelect, whereSegment);
if (null != sqlSegment) {
plainSelect.setWhere(sqlSegment);
}
}
}4、創(chuàng)建處理類(lèi),動(dò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 查詢(xún)對(duì)象
* @param whereSegment 查詢(xún)條件片段
* @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名稱(chēng)
String className = whereSegment.substring(0, whereSegment.lastIndexOf("."));
//獲取方法名
String methodName = whereSegment.substring(whereSegment.lastIndexOf(".") + 1);
Table fromItem = (Table) plainSelect.getFromItem();
// 有別名用別名,無(wú)別名用表名,防止字段沖突報(bào)錯(cuò)
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("開(kāi)始進(jìn)行權(quán)限過(guò)濾,where: {},mappedStatementId: {}", where, whereSegment);
// 把集合轉(zhuǎn)變?yōu)镴SQLParser需要的元素列表
ItemsList ids = new ExpressionList(dataIds.stream().map(StringValue::new).collect(Collectors.toList()));
//in表達(dá)式的寫(xiě)法
InExpression inExpressiondept = null;
String key = appManageConfig.getList().get(type);
inExpressiondept = new InExpression(new Column(mainTableName + "." + key), ids);
return new AndExpression(where, inExpressiondept);
}
}
//說(shuō)明無(wú)權(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)用程序類(lèi)型權(quán)限控制
- mp:小程序類(lèi)型權(quán)限控制
7、數(shù)據(jù)攔截效果:

到此這篇關(guān)于MybatisPlus實(shí)現(xiàn)數(shù)據(jù)攔截的使用示例的文章就介紹到這了,更多相關(guān)MybatisPlus 數(shù)據(jù)攔截 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java集合框架 arrayblockingqueue應(yīng)用分析
ArrayBlockingQueue是一個(gè)由數(shù)組支持的有界阻塞隊(duì)列。此隊(duì)列按 FIFO(先進(jìn)先出)原則對(duì)元素進(jìn)行排序。隊(duì)列的頭部 是在隊(duì)列中存在時(shí)間最長(zhǎng)的元素2012-11-11
Spring事務(wù)中的事務(wù)傳播行為使用方式詳解
Spring框架作為一個(gè)輕量級(jí)的開(kāi)源框架,在企業(yè)應(yīng)用開(kāi)發(fā)中被廣泛使用,在Spring事務(wù)管理中,事務(wù)傳播行為是非常重要的一部分,它定義了方法如何參與到已經(jīng)存在的事務(wù)中或者如何開(kāi)啟新的事務(wù),本文將詳細(xì)介紹Spring事務(wù)中的幾種事務(wù)傳播行為,詳細(xì)講解具體使用方法2023-06-06
MybatisPlus實(shí)現(xiàn)分頁(yè)效果并解決錯(cuò)誤問(wèn)題:cant?found?IPage?for?args
這篇文章主要介紹了MybatisPlus實(shí)現(xiàn)分頁(yè)效果并解決錯(cuò)誤:cant?found?IPage?for?args,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
快速學(xué)會(huì)Dubbo的配置環(huán)境及相關(guān)配置
本文主要講解Dubbo的環(huán)境與配置,文中運(yùn)用大量代碼和圖片講解的非常詳細(xì),需要學(xué)習(xí)或用到相關(guān)知識(shí)的小伙伴可以參考這篇文章2021-09-09
Java拷貝數(shù)組方法Arrays.copyOf()是地址傳遞的證明實(shí)例
今天小編就為大家分享一篇關(guān)于Java拷貝數(shù)組方法Arrays.copyOf()是地址傳遞的證明實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
Java使用JDK與Cglib動(dòng)態(tài)代理技術(shù)統(tǒng)一管理日志記錄
這篇文章主要介紹了Java使用JDK與Cglib動(dòng)態(tài)代理技術(shù)統(tǒng)一管理日志記錄,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
Java如何獲取對(duì)象屬性及對(duì)應(yīng)值
這篇文章主要介紹了Java如何獲取對(duì)象屬性及對(duì)應(yīng)值,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
解決myBatis中openSession()自動(dòng)提交的問(wèn)題
在學(xué)習(xí)MySQL過(guò)程中,發(fā)現(xiàn)插入操作自動(dòng)提交,問(wèn)題原因可能是myBatis中的openSession()方法設(shè)置了自動(dòng)提交,或者是MySQL的默認(rèn)引擎設(shè)置為不支持事務(wù)的MyISAM,解決辦法包括更改myBatis的提交設(shè)置或?qū)ySQL表的引擎改為InnoDB2024-09-09
java小知識(shí)之查詢(xún)數(shù)據(jù)庫(kù)數(shù)據(jù)的元信息
這篇文章主要給大家介紹了關(guān)于java小知識(shí)之查詢(xún)數(shù)據(jù)庫(kù)數(shù)據(jù)的元信息,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-10-10

