我們開發系統涉及權限的時候,會處理到用戶和角色的關系
通常情況下,我們會建一個用戶角色關系映射表:user_role_mapping
字段有id,user_id,role_id
如果某個用戶有多個角色,那么在user_role_mapping表中是有多條記錄的
也有特殊的處理方式
在用戶表user中新建一個字段role_ids記錄
如果某個用戶有多個角色,那么在role_ids記錄的值是 1,2,多個角色用逗號分隔
添加新的角色
那我們批量給用戶(某個組織下的用戶)添加新的角色的時候該如何處理呢?
簡單來說分為三種情況:
1.如果用戶已經存在新增的角色,這個時候是不需要修改的,我們保持這一批用戶權限不變
2.如果用戶從未設置過角色(null),或者角色字段為空,我們直接給這一批用戶添加權限:set role_ids = 新role_id
3.如果用戶設置過多種角色(注意要排除包含新角色的情況),比如上圖用戶666666的角色有9和10,我們在給他添加角色11,最新的role_ids的值是9,10,11,我們需要 set role_ids = concat(role_id,'',' 新role_id')即可
綜上所訴語句如下
UPDATE user set role_ids = 新role_id WHERE dept_id IN ('deptid1','deptid2') AND (role_ids = '' OR role_ids is null);
UPDATE user set role_ids = 新role_id WHERE dept_id IN ('deptid1','deptid2') AND LENGTH(role_ids ) > 0 AND LOCATE(新role_id,role_ids ) = 0;
解釋 LOCATE(新role_id,role_ids ) = 0
返回字段 role_ids 中字符串 新role_id 第一次出現的位置,此處值為0,找不到,表示用戶的多個角色並不包含新的角色
批量修改的時候需要執行以上兩條語句。
刪除角色
我們處理了添加新角色操作,接下來處理刪除角色。看明白的同學,應該知道,我們操作的條件核心是定位字符串位置,操作字符串。
刪除的情況分析如下:
1.如果用戶包含一個角色,直接置空即可。
2.如果用戶包含多個角色,且刪除的角色出現在最后的位置,需要替換 ',role_id' 為空
3.如果用戶包含多個角色,且刪除的角色出現在中間的位置的位置,需要替換 ',role_id' 為空
4.如果用戶包含多個角色,且刪除的角色出現在第一位,需要替換 'role_id,' 為空
綜上所訴:情況2和情況3,操作一致,我們可以當做一種情況處理
整理語句如下:
UPDATE user set role_ids = REPLACE(role_ids,'刪除的role_id','') WHERE role_ids = '刪除的role_id';
UPDATE ser set role_ids = REPLACE(role_ids,CONCAT(',','刪除的role_id'),'') WHERE LOCATE(CONCAT(',','刪除的role_id',','),role_ids) > 1
OR (LOCATE(CONCAT(',','刪除的role_id),role_ids) = LENGTH(role_ids) - LENGTH('刪除的role_id') AND LENGTH(role_ids) > LENGTH(CONCAT(',','刪除的role_id)))
UPDATE user set role_ids = REPLACE(role_ids,CONCAT('刪除的role_id',','),'') WHERE LOCATE(CONCAT('刪除的role_id',','),role_ids) = 1
解釋 LOCATE(CONCAT('刪除的role_id',','),role_ids) = 1
CONCAT('刪除的role_id',',') 字符串拼接 比如 CONCAT('9',',') 結果是字符串:9,
LOCATE('9,',role_ids) = 1 確保要刪除角色是在角色字符串第一位
LOCATE(',9,',role_ids) > 1 確保要刪除角色是在角色字符串中間的位置
LOCATE(',9',role_ids) = LENGTH(role_ids) - LENGTH('9') AND LENGTH(role_ids) > LENGTH(',9') 確保要刪除角色是在角色字符串最后的位置