Shiro表结构设计
表設計
開發用戶-角色-權限管理系統,首先我們需要知道用戶-角色-權限管理系統的表結構設計。
在用戶-角色-權限管理系統找那個一般會涉及5張表,分別為:
1.sys_users用戶表
2.sys_roles角色表
3.sys_permissions權限表(或資源表)
4.sys_users_roles用戶-角色關聯表
5.sys_roles_permissions角色-權限關聯表(或角色-資源關聯表)
詳細的建表信息如下
sys_users
解釋
用戶表中至少包含以上的字段,主鍵id、用戶名username、密碼password、鹽值salt(因為密碼是經過Shiro加密的,需要通過鹽值校驗,由Shiro生成,不需要用戶手動填寫)、角色列表roleId(這個字段不是必須的,僅實現在展示用戶信息的時候能同時展示用戶當前角色)、是否鎖定locked(決定當前賬戶是否是鎖定的)。
創建新的用戶,僅需要輸入用戶名和密碼即可,鹽值由Shiro生成,角色列表和是否鎖定都可以在后期管理。
其中是否鎖定字段類型為tinyint(1),設置這種類型,數據庫中實際存儲的是int類型數據,一般是0和1,在使用Mybatis取這個字段的數據時,Mybatis會自動將tinyint(1)字段值為0的轉換成false,將字段值為1以上的轉換為true。
sys_roles
解釋
角色表中role角色名稱一般為存儲著類似user:create這種格式,Shiro在Realm中校驗用戶身份的時候會通過role這個字段值進行校驗;description是此角色的描述信息,比如用戶創建。
其中pid表示父節點,就是說,當前的角色可能有上級節點,比如老師,這個角色可能就有父節點計科教師,如果存在父節點,這個字段值就是父級節點的ID,根據這個ID,在展示數據的時候就很方便的展示出其在哪個父節點下。
available表示當前節點是否鎖定,同樣是tinyint(1)類型,如果為false就說明沒有鎖定。
sys_users_roles
解釋
用戶角色表就比較簡單了,僅僅包含了主鍵id、用戶user_id、角色role_id;這張表主要描述指定用戶與角色間的依賴關系。其中用戶表與角色表是一對多的關系,一個用戶可以擁有多個角色。
sys_permissions
解釋
權限表和角色表類似,其中不同的字段是rid,這個字段表示此權限關聯的角色的id值,當然不是必要的,但是后端角色更新時用到了,后面會介紹。
sys_roles_permissions
解釋
角色-權限表和用戶-角色表類似,包含了主鍵id、角色role_id、權限permission_id,主要描述角色和權限間的依賴關系,同樣,角色和權限間也是一對多的關系,一個角色會關聯多個權限。
schema.sql
上述表設計的源碼如下:
拓展
上面就是當前用戶-角色-權限系統的表設計。細心的你可能會發現這些表中并不包含外鍵約束。
為什么不設計外鍵呢?
可能你會跟我一樣有這樣的疑問。比如用戶表和角色表間,我們這里創建了用戶-角色表來實現兩者的關聯;并沒有通過給兩張表建立外鍵來實現一對多、多對多的關聯關系。
因為如果你要建立外鍵來關聯兩張表,你需要遇到如下:
如果兩張表之間存在一對多的關系,在給一的一方新增數據的時候,你要考慮多的一方是否存在指定的id。
如果兩張表之間存在一對多的關系,在刪除多的一方時你要先刪除其關聯的一的一方,再刪除多的一方。
…
也就是說如果使用了外鍵關聯,那么在對表進行數據操作時就必須考慮另一張關聯的表,相當于兩張表就綁在一起了,操作這張表就必須考慮另一張關聯表。
但是實際中,我們不想立即就修改或更新關聯表的數據,我可能一會再去更新另一張關聯表的數據,那么就產生了這種方式:通過單獨建立一張關聯來實現兩張表的數據關聯。
所以,我建議大家在設計表時盡量減少表與表直接的外鍵約束,這樣能避免很多麻煩,并且兩張表之間的關聯關系也會格外清晰。
實例
上面創建了用戶-角色-權限表以及其關聯表,下面就介紹一些實際的案例吧!
初始化表
查詢
根據用戶名查詢其角色
[mysql> SELECT r.id, r.role, r.description FROM sys_users u, sys_roles r, sys_users_roles ur WHERE u.username = 'TyCoding' AND u.id = ur.user_id AND r.id = ur.role_id; +----+-------+-------------+ | id | role | description | +----+-------+-------------+ | 21 | admin | 管理員 | +----+-------+-------------+ 1 row in set (0.00 sec)從上面的SQL中足以看出,通過關聯表查詢另一張關聯的數據要點在于WHERE條件中添加關聯表與兩張表的關系,在這里即是關聯表中存在兩張表的主鍵id,所以把相同的字段加入WHERE條件過濾就能查詢到了。
根據用戶名查詢其權限
[mysql> SELECT p.id, p.permission, p.description FROM sys_users u, sys_roles r, sys_users_roles ur, sys_permissions p, sys_roles_permissions rp WHERE u.username = 'TyCoding' AND u.id = ur.user_id AND r.id = ur.role_id AND r.id = rp.role_id AND p.id = rp.permission_id; +----+-------------+--------------+ | id | permission | description | +----+-------------+--------------+ | 31 | user:create | 用戶創建 | +----+-------------+--------------+ 1 row in set (0.00 sec)根據角色id查詢其權限
[mysql> SELECT p.id, p.description FROM sys_permissions p, sys_roles r, sys_roles_permissions rp WHERE r.id = 21 AND rp.role_id = r.id AND rp.permission_id = p.id; +----+--------------+ | id | description | +----+--------------+ | 31 | 用戶創建 | +----+--------------+ 1 row in set (0.00 sec)更新user表中role_id字段
我們設計的sys_users表中,存在一個字段role_id,目的是用來展示當前用戶關聯的角色名稱,但是我們直接更新sys_roles表的description字段時,又不會更新sys_users表中的role_id字段。
所以,這里我們要通過更新的角色數據來更新sys_users表中的role_id字段。
根據權限ID查詢其角色
[mysql> SELECT r.id, r.description, r.pid FROM sys_permissions p, sys_roles r, sys_roles_permissions rp WHERE p.id = 31 AND p.id = rp.permission_id AND r.id = rp.role_id; +----+-------------+------+ | id | description | pid | +----+-------------+------+ | 21 | 管理員 | 0 | +----+-------------+------+ 1 row in set (0.00 sec)總結
以上是生活随笔為你收集整理的Shiro表结构设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot---整合shiro
- 下一篇: python2中文字符串遍历乱码_完美解