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
上述表設計的源碼如下:

-- create database shiro default character set utf8;drop table if exists sys_users;
drop table if exists sys_roles;
drop table if exists sys_permissions;
drop table if exists sys_users_roles;
drop table if exists sys_roles_permissions;create table sys_users (id bigint auto_increment comment '編號',username varchar(100) comment '用戶名',password varchar(100) comment '密碼',salt varchar(100) comment '鹽值',role_id varchar(50) comment '角色列表',locked bool default false comment '是否鎖定',constraint pk_sys_users primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_sys_users_username on sys_users(username);create table sys_roles (id bigint auto_increment comment '角色編號',role varchar(100) comment '角色名稱',description varchar(100) comment '角色描述',pid bigint comment '父節點',available bool default false comment '是否鎖定',constraint pk_sys_roles primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_sys_roles_role on sys_roles(role);create table sys_permissions (id bigint auto_increment comment '編號',permission varchar(100) comment '權限編號',description varchar(100) comment '權限描述',rid bigint comment '此權限關聯角色的id',available bool default false comment '是否鎖定',constraint pk_sys_permissions primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_sys_permissions_permission on sys_permissions(permission);create table sys_users_roles (id  bigint auto_increment comment '編號',user_id bigint comment '用戶編號',role_id bigint comment '角色編號',constraint pk_sys_users_roles primary key(id)
) charset=utf8 ENGINE=InnoDB;create table sys_roles_permissions (id bigint auto_increment comment '編號',role_id bigint comment '角色編號',permission_id bigint comment '權限編號',constraint pk_sys_roles_permissions primary key(id)
) charset=utf8 ENGINE=InnoDB;

拓展
上面就是當前用戶-角色-權限系統的表設計。細心的你可能會發現這些表中并不包含外鍵約束。
為什么不設計外鍵呢?
可能你會跟我一樣有這樣的疑問。比如用戶表和角色表間,我們這里創建了用戶-角色表來實現兩者的關聯;并沒有通過給兩張表建立外鍵來實現一對多、多對多的關聯關系。
因為如果你要建立外鍵來關聯兩張表,你需要遇到如下:

如果兩張表之間存在一對多的關系,在給一的一方新增數據的時候,你要考慮多的一方是否存在指定的id。
如果兩張表之間存在一對多的關系,在刪除多的一方時你要先刪除其關聯的一的一方,再刪除多的一方。

也就是說如果使用了外鍵關聯,那么在對表進行數據操作時就必須考慮另一張關聯的表,相當于兩張表就綁在一起了,操作這張表就必須考慮另一張關聯表。
但是實際中,我們不想立即就修改或更新關聯表的數據,我可能一會再去更新另一張關聯表的數據,那么就產生了這種方式:通過單獨建立一張關聯來實現兩張表的數據關聯。
所以,我建議大家在設計表時盡量減少表與表直接的外鍵約束,這樣能避免很多麻煩,并且兩張表之間的關聯關系也會格外清晰。
實例
上面創建了用戶-角色-權限表以及其關聯表,下面就介紹一些實際的案例吧!
初始化表

insert into sys_users values(1,'TyCoding','123','salt','管理員',0);
insert into sys_roles values(21,'user:create','用戶創建',0,0);
insert into sys_permissions values(31,'user:create','用戶創建',0,0);
insert into sys_users_roles values(1,1,21);
insert into sys_roles_permissions values(1,21,31);

查詢

根據用戶名查詢其角色

[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字段。

[mysql> UPDATE sys_users u, sys_users_roles ur SET u.role_id = '管理員-更新' WHERE ur.role_id = 21 AND u.id = ur.user_id;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> SELECT * FROM sys_users;
+----+----------+----------+------+------------------+--------+
| id | username | password | salt | role_id          | locked |
+----+----------+----------+------+------------------+--------+
|  1 | TyCoding | 123      | salt | 管理員-更新      |      0 |
+----+----------+----------+------+------------------+--------+
1 row in set (0.00 sec)

根據權限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)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250079.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250079.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250079.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[Java核心技術(卷I)] - 簡易的日歷

參考 - P102~P103 1. 目標 生成一個日歷,格式如下圖所示。 ps: 當前的天數需要標記為* 2. 核心 對日歷的變量 import java.time.*; public class CalendarTest{public static void main(String[] args) {LocalDate date LocalDate.now(); // 獲取當前日期int month date…

個人作業——福大微信公眾號使用評測

案例分析:在福州大學公眾號上,我們可以即時使用手機關注福大新聞,查看自身課表、成績等。公眾號可能存在一些小bug影響同學們的用戶體驗。本次作業中,作為一個用戶——福大的學生,將切身體驗該公眾號的功能&#xff0c…

在winform中使用wpf窗體

在winform項目,通過引用dll可以添加WPF窗體,如下 但是如果直接在winform的項目中添加wpf窗體還是有部分問題,圖片的顯示。 直接在XAML界面中用Source屬性設置圖片會出現錯誤。必須通過后臺代碼的方式來實現。 image1.Source GetImageIcon(gl…

shiro---注解

RequiresAuthentication 驗證用戶是否登錄,等同于方法subject.isAuthenticated() 結果為true時。 RequiresUser 驗證用戶是否被記憶,user有兩種含義: 一種是成功登錄的(subject.isAuthenticated() 結果為true)&…

[Java核心技術(卷I)] - Java中的參數能做什么和不能做什么

1. 參考 - P123 ~ P126 2. 你將學到 Java中對方法參數能做什么和不能做什么 方法不能修改基本數據類型的參數(數值型或布爾型)方法可以改變對象參數的狀態方法不能讓一個對象參數引用一個新的對象 3. 代碼證明 public class ParamTest {public static void main(String[] ar…

軟件構造 第五章第一節 可復用性的度量、形態和外部觀察

第五章第一節 可復用性的度量、形態和外部觀察 面向復用編程(programming for reuse):開發出可復用的軟件 基于復用編程(programming with reuse):利用已有的可復用軟件搭建應用系統 代碼復用的類型: 白盒復用:源代碼可見&#x…

洛谷團隊月賽題:題解

10pts10pts10pts 暴力算不解釋,時間復雜度O(knk2)O(knk^2)O(knk2)。 30pts30pts30pts 我們觀察到nnn很大,楊輝三角會T,直接算會上溢,所以需要預處理出111~kkk逆元再算,時間復雜度O(knnlogkn2)O(knnlogkn^2)O(knnlogkn2…

Angular Forms - 自定義 ngModel 綁定值的方式

在 Angular 應用中,我們有兩種方式來實現表單綁定——“模板驅動表單”與“響應式表單”。這兩種方式通常能夠很好的處理大部分的情況,但是對于一些特殊的表單控件,例如input[typedatetime]、input[typefile],我們需要重寫默認的表…

[web性能優化] - 使用在線工具對html、js、css進行壓縮

參考 1. 學習點 使用 在線工具對html、css、js進行壓縮學會分析壓縮前后的效率提高點 2. 解決方案: 2.1 HTML壓縮 在線壓縮nodejs提供了 html-minifier工具(在構建層對代碼進行壓縮)后端模板引擎渲染壓縮 2.2 CSS壓縮 使用html-minifier對html中的css進行壓縮使用clean-cs…

【LOJ】 #2540. 「PKUWC2018」隨機算法

題解 感覺極其神奇的狀壓dp \(dp[i][S]\)表示答案為i,然后不可選的點集為S 我們每次往答案里加一個點,然后方案數是,設原來可以選的點數是y,新加入一個點后導致了除了新加的點之外x個點不能選,那么方案就是把x個數在y …

Shiro的authc過濾器的執行流程

1.先執行isAccessAllowed(),通過subject.isAuthenticated()判斷當前session中的subject是否已經登陸過。如果在當前session即會話中已經登陸過,返回true,authc過濾器放行請求到loginUrl。 問題? 這里會有一個問題,如果我登陸成功…

SpringBoot之基礎

簡介 背景 J2EE笨重的開發 / 繁多的配置 / 低下的開發效率 / 復雜的部署流程 / 第三方技術集成難度大 特點 ① 快速創建獨立運行的spring項目以及主流框架集成 ② 使用嵌入式的Servlet容器, 應用無需達成war包 ③ starters自動依賴和版本控制 ④ 大量自動配置, 簡化開發, 也可修…

[Java核心技術(卷I)] - vscode手動編譯運行繼承類

參考 - P160~P161 主要有3個類: 一個測試類(ManagerTest)、一個子類(Manager)、一個父類(Employee) 注意點: -1. 使用 javac -d . *.java進行預編譯 目錄結構入下: 此時會生成目錄結構如下: 之后運行 java com.inheritance.ManagerTest 附上幾個類的代碼 // com.inhe…

mysql常用語句和函數

mysql語句如果長期不寫,就會忘掉,所以要時常復習,溫故而知新。 1.select length("中國人"),select char_length("中國人"); 2建立數據庫的語句 use new_schema;create table ta(id int primary key);這是小括號&#xff…

shiro框架@RequiresPermissions 解釋

RequiresAuthentication 驗證用戶是否登錄,等同于方法subject.isAuthenticated() 結果為true時。 RequiresUser 驗證用戶是否被記憶,user有兩種含義: 一種是成功登錄的(subject.isAuthenticated() 結果為true)&…

【Social Listening實戰】當數據分析遭遇心理動力學:用戶深層次的情感需求浮出水面...

本文轉自知乎 作者:蘇格蘭折耳喵 ————————————————————————————————————————————————————— 本文篇幅較長,分為五部分,在中間部分有關于心理分析工具的介紹,案例分散在第二部…

Python 字符串切片

#-*- coding:utf-8 -*-#字符串切片names "abcdefgh"切片語法 names[起始位置:終止位置:步長] 起始位置:即字符串的下標,可以是正序下標(0,1,2...),也可以是逆序下標(-1,-2,-3...) 終止位置:也是字符串的下標,但是和起始位置下標不…

[Java核心技術(卷Ⅰ)] - 判斷相等

參考 - P184 public boolean equals(Object otherObject) {// a quick test to see if the objects are identicalif (this otherObject) return true;// must return false if the explicit parameter is nullif (otherObject null) return null;// if the classes dont ma…

Oracle 11g DG主庫節點2 ORA-00245: control file backup fail

--節點1報錯 Sun Dec 09 08:29:57 2018Control file backup creation failed: failure to open backup target file /u01/app/oracle/product/11.2.0/db_1/dbs/snapcf_zwdb.ctl.Errors in file /u01/app/oracle/diag/rdbms/zwdb/zwdb2/trace/zwdb2_arc0_167660.trc:ORA-27037: …

hive字符函數

轉載于:https://www.cnblogs.com/ggzhangxiaochao/p/9222732.html