1、使用了MySQL 的with 關鍵字 配合 RECURSIVE 遞歸查出用戶的菜單。
2、例子如下
RBAC(Role-Based Access Control)即:基於角色的權限控制。通過角色關聯用戶,角色關聯權限的方式間接賦予用戶權限。
下面設計5個表來完成這個控制。
t_menu表、t_role表、t_role_menu表、t_user表、t_user_role表。其中t_role_menu表示每個角色里擁有的菜單,t_user_role表示每個用戶擁有多少個角色。

-- ---------------------------- -- Table structure for t_menu -- ---------------------------- DROP TABLE IF EXISTS `t_menu`; CREATE TABLE `t_menu` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '菜單名稱', `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '菜單路徑', `permission_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '菜單權限碼', `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '圖標', `parent_id` bigint(0) NULL DEFAULT NULL COMMENT '父級ID', `sort_number` int(0) NULL DEFAULT NULL COMMENT '排序', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for t_role -- ---------------------------- DROP TABLE IF EXISTS `t_role`; CREATE TABLE `t_role` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for t_role_menu -- ---------------------------- DROP TABLE IF EXISTS `t_role_menu`; CREATE TABLE `t_role_menu` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `role_id` bigint(0) NULL DEFAULT NULL, `menu_id` bigint(0) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for t_user -- ---------------------------- DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for t_user_role -- ---------------------------- DROP TABLE IF EXISTS `t_user_role`; CREATE TABLE `t_user_role` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `user_id` bigint(0) NULL DEFAULT NULL, `role_id` bigint(0) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
3、查詢某個用戶的菜單列表如下
WITH RECURSIVE r(`id`, `name`, `url`, `permission_code`, `icon`, `parent_id`, `sort_number`) AS ( SELECT DISTINCT d.* FROM t_user_role a LEFT JOIN t_role b ON a.role_id = b.id LEFT JOIN t_role_menu c ON b.id = c.role_id LEFT JOIN t_menu d ON c.menu_id = d.id WHERE a.user_id = {userId} UNION DISTINCT SELECT m.* FROM t_menu m,r WHERE m.id = r.parent_id ) SELECT * FROM r;