0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何利用MyBatis Plus去實現(xiàn)數(shù)據(jù)權(quán)限控制呢?

jf_ro2CN3Fa ? 來源:CSDN ? 2023-08-23 10:40 ? 次閱讀

前言背景

平時開發(fā)中遇到根據(jù)當前用戶的角色,只能查看數(shù)據(jù)權(quán)限范圍的數(shù)據(jù)需求。列表實現(xiàn)方案有兩種,一是在開發(fā)初期就做好判斷賽選,但如果這個需求是中途加的,或不希望每個接口都加一遍,就可以方案二加攔截器的方式。在mybatis執(zhí)行sql前修改語句,限定where范圍。

當然攔截器生效后是全局性的,如何保證只對需要的接口進行攔截和轉(zhuǎn)化,就可以應(yīng)用注解進行識別

因此具體需要哪些步驟就明確了

創(chuàng)建注解類

創(chuàng)建攔截器實現(xiàn)InnerInterceptor接口,重寫查詢方法

創(chuàng)建處理類,獲取數(shù)據(jù)權(quán)限 SQL 片段,設(shè)置where

將攔截器加到MyBatis-Plus插件中

自定義注解

importjava.lang.annotation.ElementType;
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
importjava.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public@interfaceUserDataPermission{
}

攔截器

importcom.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
importcom.baomidou.mybatisplus.core.toolkit.PluginUtils;
importcom.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
importcom.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
importlombok.*;
importnet.sf.jsqlparser.expression.Expression;
importnet.sf.jsqlparser.statement.select.PlainSelect;
importnet.sf.jsqlparser.statement.select.Select;
importnet.sf.jsqlparser.statement.select.SelectBody;
importnet.sf.jsqlparser.statement.select.SetOperationList;
importorg.apache.ibatis.executor.Executor;
importorg.apache.ibatis.mapping.BoundSql;
importorg.apache.ibatis.mapping.MappedStatement;
importorg.apache.ibatis.session.ResultHandler;
importorg.apache.ibatis.session.RowBounds;

importjava.sql.SQLException;
importjava.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper=true)
@EqualsAndHashCode(callSuper=true)
publicclassMyDataPermissionInterceptorextendsJsqlParserSupportimplementsInnerInterceptor{

/**
*數(shù)據(jù)權(quán)限處理器
*/
privateMyDataPermissionHandlerdataPermissionHandler;

@Override
publicvoidbeforeQuery(Executorexecutor,MappedStatementms,Objectparameter,RowBoundsrowBounds,ResultHandlerresultHandler,BoundSqlboundSql)throwsSQLException{
if(InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())){
return;
}
PluginUtils.MPBoundSqlmpBs=PluginUtils.mpBoundSql(boundSql);
mpBs.sql(this.parserSingle(mpBs.sql(),ms.getId()));
}

@Override
protectedvoidprocessSelect(Selectselect,intindex,Stringsql,Objectobj){
SelectBodyselectBody=select.getSelectBody();
if(selectBodyinstanceofPlainSelect){
this.setWhere((PlainSelect)selectBody,(String)obj);
}elseif(selectBodyinstanceofSetOperationList){
SetOperationListsetOperationList=(SetOperationList)selectBody;
ListselectBodyList=setOperationList.getSelects();
selectBodyList.forEach(s->this.setWhere((PlainSelect)s,(String)obj));
}
}

/**
*設(shè)置where條件
*
*@paramplainSelect查詢對象
*@paramwhereSegment查詢條件片段
*/
privatevoidsetWhere(PlainSelectplainSelect,StringwhereSegment){

ExpressionsqlSegment=this.dataPermissionHandler.getSqlSegment(plainSelect,whereSegment);
if(null!=sqlSegment){
plainSelect.setWhere(sqlSegment);
}
}
}

攔截器處理器

基礎(chǔ)只涉及 = 表達式,要查詢集合范圍 in 看進階版用例

importcn.hutool.core.collection.CollectionUtil;
importlombok.SneakyThrows;
importlombok.extern.slf4j.Slf4j;
importnet.sf.jsqlparser.expression.Alias;
importnet.sf.jsqlparser.expression.Expression;
importnet.sf.jsqlparser.expression.HexValue;
importnet.sf.jsqlparser.expression.StringValue;
importnet.sf.jsqlparser.expression.operators.conditional.AndExpression;
importnet.sf.jsqlparser.expression.operators.relational.EqualsTo;
importnet.sf.jsqlparser.expression.operators.relational.ExpressionList;
importnet.sf.jsqlparser.expression.operators.relational.InExpression;
importnet.sf.jsqlparser.expression.operators.relational.ItemsList;
importnet.sf.jsqlparser.schema.Column;
importnet.sf.jsqlparser.schema.Table;
importnet.sf.jsqlparser.statement.select.PlainSelect;

importjava.lang.reflect.Method;
importjava.util.List;
importjava.util.Objects;
importjava.util.Set;
importjava.util.stream.Collectors;

@Slf4j
publicclassMyDataPermissionHandler{

/**
*獲取數(shù)據(jù)權(quán)限SQL片段
*
*@paramplainSelect查詢對象
*@paramwhereSegment查詢條件片段
*@returnJSqlParser條件表達式
*/
@SneakyThrows(Exception.class)
publicExpressiongetSqlSegment(PlainSelectplainSelect,StringwhereSegment){
//待執(zhí)行SQLWhere條件表達式
Expressionwhere=plainSelect.getWhere();
if(where==null){
where=newHexValue("1=1");
}
log.info("開始進行權(quán)限過濾,where:{},mappedStatementId:{}",where,whereSegment);
//獲取mapper名稱
StringclassName=whereSegment.substring(0,whereSegment.lastIndexOf("."));
//獲取方法名
StringmethodName=whereSegment.substring(whereSegment.lastIndexOf(".")+1);
TablefromItem=(Table)plainSelect.getFromItem();
//有別名用別名,無別名用表名,防止字段沖突報錯
AliasfromItemAlias=fromItem.getAlias();
StringmainTableName=fromItemAlias==null?fromItem.getName():fromItemAlias.getName();
//獲取當前mapper的方法
Method[]methods=Class.forName(className).getMethods();
//遍歷判斷mapper的所以方法,判斷方法上是否有UserDataPermission
for(Methodm:methods){
if(Objects.equals(m.getName(),methodName)){
UserDataPermissionannotation=m.getAnnotation(UserDataPermission.class);
if(annotation==null){
returnwhere;
}
//1、當前用戶Code
Useruser=SecurityUtils.getUser();
//查看自己的數(shù)據(jù)
//=表達式
EqualsTousesEqualsTo=newEqualsTo();
usesEqualsTo.setLeftExpression(newColumn(mainTableName+".creator_code"));
usesEqualsTo.setRightExpression(newStringValue(user.getUserCode()));
returnnewAndExpression(where,usesEqualsTo);
}
}
//說明無權(quán)查看,
where=newHexValue("1=2");
returnwhere;
}

}

將攔截器加到MyBatis-Plus插件中

如果你之前項目配插件 ,直接用下面方式就行

@Bean
publicMybatisPlusInterceptormybatisPlusInterceptor(){
MybatisPlusInterceptorinterceptor=newMybatisPlusInterceptor();
//添加數(shù)據(jù)權(quán)限插件
MyDataPermissionInterceptordataPermissionInterceptor=newMyDataPermissionInterceptor();
//添加自定義的數(shù)據(jù)權(quán)限處理器
dataPermissionInterceptor.setDataPermissionHandler(newMyDataPermissionHandler());
interceptor.addInnerInterceptor(dataPermissionInterceptor);
interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));
returninterceptor;
}

但如果你項目之前是依賴包依賴,或有公司內(nèi)部統(tǒng)一攔截設(shè)置好,也可以往MybatisPlusInterceptor進行插入,避免影響原有項目配置

@Bean
publicMyDataPermissionInterceptormyInterceptor(MybatisPlusInterceptormybatisPlusInterceptor){
MyDataPermissionInterceptorsql=newMyDataPermissionInterceptor();
sql.setDataPermissionHandler(newMyDataPermissionHandler());
Listlist=newArrayList<>();
//添加數(shù)據(jù)權(quán)限插件
list.add(sql);
//分頁插件
mybatisPlusInterceptor.setInterceptors(list);
list.add(newPaginationInnerInterceptor(DbType.MYSQL));
returnsql;
}

以上就是簡單版的是攔截器修改語句使用

使用方式

在mapper層添加注解即可

@UserDataPermission
ListselectAllCustomerPage(IPagepage,@Param("customerName")StringcustomerName);

基礎(chǔ)班只是能用,業(yè)務(wù)功能沒有特別約束,先保證能跑起來

進階版 解決兩個問題:

加了角色,用角色決定范圍

解決不是mapper層自定義sql查詢問題。

兩個是完全獨立的問題 ,可根據(jù)情況分開解決

解決不是mapper層自定義sql查詢問題。

例如我們名稱簡單的sql語句 直接在Service層用mybatisPluse自帶的方法

xxxxService.list(WrapperqueryWrapper)
xxxxService.page(newPage<>(),WrapperqueryWrapper)

以上這種我應(yīng)該把注解加哪里呢

因為service層,本質(zhì)上還是調(diào)mapper層, 所以還是在mapper層做文章,原來的mapper實現(xiàn)了extends BaseMapper 接口,所以能夠查詢,我們要做的就是在 mapper層中間套一個中間接口,來方便我們加注解

xxxxxMapper——》DataPermissionMapper(中間)——》BaseMapper

根據(jù)自身需要,在重寫的接口方法上加注解即可,這樣就影響原先的代碼

4d7a8f2c-40d8-11ee-a2ef-92fbcf53809c.png

importcom.baomidou.mybatisplus.core.conditions.Wrapper;
importcom.baomidou.mybatisplus.core.mapper.BaseMapper;
importcom.baomidou.mybatisplus.core.metadata.IPage;
importcom.baomidou.mybatisplus.core.toolkit.Constants;
importorg.apache.ibatis.annotations.Param;

importjava.io.Serializable;
importjava.util.Collection;
importjava.util.List;
importjava.util.Map;

publicinterfaceDataPermissionMapperextendsBaseMapper{

/**
*根據(jù)ID查詢
*
*@paramid主鍵ID
*/
@Override
@UserDataPermission
TselectById(Serializableid);

/**
*查詢(根據(jù)ID批量查詢)
*
*@paramidList主鍵ID列表(不能為null以及empty)
*/
@Override
@UserDataPermission
ListselectBatchIds(@Param(Constants.COLLECTION)CollectionidList);

/**
*查詢(根據(jù)columnMap條件)
*
*@paramcolumnMap表字段map對象
*/
@Override
@UserDataPermission
ListselectByMap(@Param(Constants.COLUMN_MAP)MapcolumnMap);

/**
*根據(jù)entity條件,查詢一條記錄
*
*@paramqueryWrapper實體對象封裝操作類(可以為null)
*/
@Override
@UserDataPermission
TselectOne(@Param(Constants.WRAPPER)WrapperqueryWrapper);

/**
*根據(jù)Wrapper條件,查詢總記錄數(shù)
*
*@paramqueryWrapper實體對象封裝操作類(可以為null)
*/
@Override
@UserDataPermission
IntegerselectCount(@Param(Constants.WRAPPER)WrapperqueryWrapper);

/**
*根據(jù)entity條件,查詢?nèi)坑涗?*
*@paramqueryWrapper實體對象封裝操作類(可以為null)
*/
@Override
@UserDataPermission
ListselectList(@Param(Constants.WRAPPER)WrapperqueryWrapper);

/**
*根據(jù)Wrapper條件,查詢?nèi)坑涗?*
*@paramqueryWrapper實體對象封裝操作類(可以為null)
*/
@Override
@UserDataPermission
List>selectMaps(@Param(Constants.WRAPPER)WrapperqueryWrapper);

/**
*根據(jù)Wrapper條件,查詢?nèi)坑涗?*

注意:只返回第一個字段的值

* *@paramqueryWrapper實體對象封裝操作類(可以為null) */ @Override @UserDataPermission ListselectObjs(@Param(Constants.WRAPPER)WrapperqueryWrapper); /** *根據(jù)entity條件,查詢?nèi)坑涗洠ú⒎摚?* *@parampage分頁查詢條件(可以為RowBounds.DEFAULT) *@paramqueryWrapper實體對象封裝操作類(可以為null) */ @Override @UserDataPermission >EselectPage(Epage,@Param(Constants.WRAPPER)WrapperqueryWrapper); /** *根據(jù)Wrapper條件,查詢?nèi)坑涗洠ú⒎摚?* *@parampage分頁查詢條件 *@paramqueryWrapper實體對象封裝操作類 */ @Override @UserDataPermission >>EselectMapsPage(Epage,@Param(Constants.WRAPPER)WrapperqueryWrapper); }

解決角色控制查詢范圍

引入角色,我們先假設(shè)有三種角色,按照常規(guī)的業(yè)務(wù)需求,一種是管理員查看全部、一種是部門管理查看本部門、一種是僅查看自己。

有了以上假設(shè),就可以設(shè)置枚舉類編寫業(yè)務(wù)邏輯, 對是業(yè)務(wù)邏輯,所以我們只需要更改”攔截器處理器類“

建立范圍枚舉

建立角色枚舉以及范圍關(guān)聯(lián)關(guān)系

重寫攔截器處理方法

范圍枚舉

@AllArgsConstructor
@Getter
publicenumDataScope{
//Scope數(shù)據(jù)權(quán)限范圍:ALL(全部)、DEPT(部門)、MYSELF(自己)
ALL("ALL"),
DEPT("DEPT"),
MYSELF("MYSELF");
privateStringname;
}

角色枚舉

@AllArgsConstructor
@Getter
publicenumDataPermission{

//枚舉類型根據(jù)范圍從前往后排列,避免影響getScope
//Scope數(shù)據(jù)權(quán)限范圍:ALL(全部)、DEPT(部門)、MYSELF(自己)
DATA_MANAGER("數(shù)據(jù)管理員","DATA_MANAGER",DataScope.ALL),
DATA_AUDITOR("數(shù)據(jù)審核員","DATA_AUDITOR",DataScope.DEPT),
DATA_OPERATOR("數(shù)據(jù)業(yè)務(wù)員","DATA_OPERATOR",DataScope.MYSELF);

privateStringname;
privateStringcode;
privateDataScopescope;


publicstaticStringgetName(Stringcode){
for(DataPermissiontype:DataPermission.values()){
if(type.getCode().equals(code)){
returntype.getName();
}
}
returnnull;
}

publicstaticStringgetCode(Stringname){
for(DataPermissiontype:DataPermission.values()){
if(type.getName().equals(name)){
returntype.getCode();
}
}
returnnull;
}

publicstaticDataScopegetScope(Collectioncode){
for(DataPermissiontype:DataPermission.values()){
for(Stringv:code){
if(type.getCode().equals(v)){
returntype.getScope();
}
}
}
returnDataScope.MYSELF;
}
}

重寫攔截器處理類 MyDataPermissionHandler

importlombok.SneakyThrows;
importlombok.extern.slf4j.Slf4j;
importnet.sf.jsqlparser.expression.Alias;
importnet.sf.jsqlparser.expression.Expression;
importnet.sf.jsqlparser.expression.HexValue;
importnet.sf.jsqlparser.expression.StringValue;
importnet.sf.jsqlparser.expression.operators.conditional.AndExpression;
importnet.sf.jsqlparser.expression.operators.relational.EqualsTo;
importnet.sf.jsqlparser.expression.operators.relational.ExpressionList;
importnet.sf.jsqlparser.expression.operators.relational.InExpression;
importnet.sf.jsqlparser.expression.operators.relational.ItemsList;
importnet.sf.jsqlparser.schema.Column;
importnet.sf.jsqlparser.schema.Table;
importnet.sf.jsqlparser.statement.select.PlainSelect;

importjava.lang.reflect.Method;
importjava.util.List;
importjava.util.Objects;
importjava.util.Set;
importjava.util.stream.Collectors;

@Slf4j
publicclassMyDataPermissionHandler{

privateRemoteRoleServiceremoteRoleService;
privateRemoteUserServiceremoteUserService;


/**
*獲取數(shù)據(jù)權(quán)限SQL片段
*
*@paramplainSelect查詢對象
*@paramwhereSegment查詢條件片段
*@returnJSqlParser條件表達式
*/
@SneakyThrows(Exception.class)
publicExpressiongetSqlSegment(PlainSelectplainSelect,StringwhereSegment){
remoteRoleService=SpringUtil.getBean(RemoteRoleService.class);
remoteUserService=SpringUtil.getBean(RemoteUserService.class);

//待執(zhí)行SQLWhere條件表達式
Expressionwhere=plainSelect.getWhere();
if(where==null){
where=newHexValue("1=1");
}
log.info("開始進行權(quán)限過濾,where:{},mappedStatementId:{}",where,whereSegment);
//獲取mapper名稱
StringclassName=whereSegment.substring(0,whereSegment.lastIndexOf("."));
//獲取方法名
StringmethodName=whereSegment.substring(whereSegment.lastIndexOf(".")+1);
TablefromItem=(Table)plainSelect.getFromItem();
//有別名用別名,無別名用表名,防止字段沖突報錯
AliasfromItemAlias=fromItem.getAlias();
StringmainTableName=fromItemAlias==null?fromItem.getName():fromItemAlias.getName();
//獲取當前mapper的方法
Method[]methods=Class.forName(className).getMethods();
//遍歷判斷mapper的所以方法,判斷方法上是否有UserDataPermission
for(Methodm:methods){
if(Objects.equals(m.getName(),methodName)){
UserDataPermissionannotation=m.getAnnotation(UserDataPermission.class);
if(annotation==null){
returnwhere;
}
//1、當前用戶Code
Useruser=SecurityUtils.getUser();
//2、當前角色即角色或角色類型(可能多種角色)
SetroleTypeSet=remoteRoleService.currentUserRoleType();

DataScopescopeType=DataPermission.getScope(roleTypeSet);
switch(scopeType){
//查看全部
caseALL:
returnwhere;
caseDEPT:
//查看本部門用戶數(shù)據(jù)
//創(chuàng)建IN表達式
//創(chuàng)建IN范圍的元素集合
ListdeptUserList=remoteUserService.listUserCodesByDeptCodes(user.getDeptCode());
//把集合轉(zhuǎn)變?yōu)镴SQLParser需要的元素列表
ItemsListdeptList=newExpressionList(deptUserList.stream().map(StringValue::new).collect(Collectors.toList()));
InExpressioninExpressiondept=newInExpression(newColumn(mainTableName+".creator_code"),deptList);
returnnewAndExpression(where,inExpressiondept);
caseMYSELF:
//查看自己的數(shù)據(jù)
//=表達式
EqualsTousesEqualsTo=newEqualsTo();
usesEqualsTo.setLeftExpression(newColumn(mainTableName+".creator_code"));
usesEqualsTo.setRightExpression(newStringValue(user.getUserCode()));
returnnewAndExpression(where,usesEqualsTo);
default:
break;
}
}

}
//說明無權(quán)查看,
where=newHexValue("1=2");
returnwhere;
}
}

以上就是全篇知識點, 需要注意的點可能有:

記得把攔截器加到MyBatis-Plus的插件中,確保生效

要有一個業(yè)務(wù)賽選標識字段, 這里用的創(chuàng)建人 creator_code, 也可以用dept_code 等等。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    18924

    瀏覽量

    227205
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    750

    瀏覽量

    43900

原文標題:巧用 MyBatis Plus 實現(xiàn)數(shù)據(jù)權(quán)限控制

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    如何利用STM32接口接收和探測實現(xiàn)數(shù)據(jù)的接收和發(fā)送

    如何利用STM32接口接收和探測實現(xiàn)數(shù)據(jù)的接收和發(fā)送?其代碼是如何
    發(fā)表于 11-17 07:12

    如何利用DW1000實現(xiàn)數(shù)據(jù)的接受與發(fā)送

    如何利用DW1000實現(xiàn)數(shù)據(jù)的接受與發(fā)送?
    發(fā)表于 02-11 06:40

    Lora sx1278是怎樣利用串口協(xié)議實現(xiàn)數(shù)據(jù)傳輸?shù)?b class='flag-5'>呢

    Lora sx1278是怎樣利用串口協(xié)議實現(xiàn)數(shù)據(jù)傳輸?shù)?b class='flag-5'>呢?其代碼該怎樣
    發(fā)表于 02-21 06:37

    MyBatis實現(xiàn)原理

    本文主要詳細介紹了MyBatis實現(xiàn)原理。mybatis底層還是采用原生jdbc來對數(shù)據(jù)庫進行操作的,只是通過 SqlSessionFactory,SqlSession Execut
    的頭像 發(fā)表于 02-24 11:25 ?6407次閱讀
    <b class='flag-5'>MyBatis</b>的<b class='flag-5'>實現(xiàn)</b>原理

    Mybatis-Plus Mybatis增強工具包

    ./oschina_soft/gitee-mybatis-plus.zip
    發(fā)表于 06-13 11:34 ?1次下載
    <b class='flag-5'>Mybatis-Plus</b> <b class='flag-5'>Mybatis</b>增強工具包

    MyBatis-Plus的使用與測試

    本文主要介紹mybatis-plus這款插件,針對springboot用戶。包括引入,配置,使用,以及擴展等常用的方面做一個匯總整理,盡量包含大家常用的場景內(nèi)容。
    的頭像 發(fā)表于 08-22 11:56 ?1173次閱讀

    Fluent Mybatis、原生MybatisMybatis Plus對比

    mapper中再組裝參數(shù)。那對比原生Mybatis, Mybatis Plus或者其他框架,F(xiàn)luentMybatis提供了哪些便利
    的頭像 發(fā)表于 09-15 15:41 ?1333次閱讀

    SpringBoot 實現(xiàn)異步記錄復雜日志

    基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、
    發(fā)表于 12-22 10:35 ?420次閱讀

    SpringBoot+ElasticSearch實現(xiàn)模糊查詢功能

    基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、
    的頭像 發(fā)表于 12-30 14:00 ?860次閱讀

    MyBatis-Plus為什么不支持聯(lián)表

    `的所有功能`MyBatis Plus Join`同樣擁有;框架的使用方式和`MyBatis Plus`一樣簡單,幾行代碼就能實現(xiàn)聯(lián)表查詢的
    的頭像 發(fā)表于 02-28 15:19 ?2231次閱讀
    <b class='flag-5'>MyBatis-Plus</b>為什么不支持聯(lián)表

    基于Mybatis攔截器實現(xiàn)數(shù)據(jù)范圍權(quán)限

    前端的菜單和按鈕權(quán)限都可以通過配置來實現(xiàn),但很多時候,后臺查詢數(shù)據(jù)數(shù)據(jù)權(quán)限需要通過手動添加SQL來
    的頭像 發(fā)表于 06-20 09:57 ?1160次閱讀
    基于<b class='flag-5'>Mybatis</b>攔截器<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>數(shù)據(jù)</b>范圍<b class='flag-5'>權(quán)限</b>

    如何實現(xiàn)基于Mybatis攔截器實現(xiàn)數(shù)據(jù)范圍權(quán)限?

    前端的菜單和按鈕權(quán)限都可以通過配置來實現(xiàn),但很多時候,后臺查詢數(shù)據(jù)數(shù)據(jù)權(quán)限需要通過手動添加SQL來
    的頭像 發(fā)表于 06-20 09:59 ?1077次閱讀
    如何<b class='flag-5'>實現(xiàn)</b>基于<b class='flag-5'>Mybatis</b>攔截器<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>數(shù)據(jù)</b>范圍<b class='flag-5'>權(quán)限</b><b class='flag-5'>呢</b>?

    你還在手寫join聯(lián)表查詢?MyBatis-Plus這樣寫太香了!

    眾所周知,mybatis plus 封裝的 mapper 不支持 join,如果需要支持就必須自己實現(xiàn)。但是對于大部分的業(yè)務(wù)場景來說,都需要多表 join,要不然就沒必要采用關(guān)系型
    的頭像 發(fā)表于 07-07 10:19 ?2185次閱讀
    你還在手寫join聯(lián)表查詢?<b class='flag-5'>MyBatis-Plus</b>這樣寫太香了!

    不好意思,list.contain 重該換換了!

    基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、
    的頭像 發(fā)表于 09-14 15:50 ?361次閱讀
    不好意思,list.contain <b class='flag-5'>去</b>重該換換了!

    使用mybatis切片實現(xiàn)數(shù)據(jù)權(quán)限控制

    一、使用方式 數(shù)據(jù)權(quán)限控制需要對查詢出的數(shù)據(jù)進行篩選,對業(yè)務(wù)入侵最少的方式就是利用mybatis
    的頭像 發(fā)表于 07-09 17:26 ?249次閱讀
    使用<b class='flag-5'>mybatis</b>切片<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>數(shù)據(jù)</b><b class='flag-5'>權(quán)限</b><b class='flag-5'>控制</b>