Mybatis实现RBAC权限模型查询
RBAC权限模型
Role-Based Access Control,中文意思是:基于角色(Role)的访问控制。这是一种广泛应用于计算机系统和网络安全领域的访问控制模型。
简单来说,就是通过将权限分配给➡角色,再将角色分配给➡用户,来实现对系统资源的访问控制。一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系
具体概念可以查看RBAC——基于角色权限的模型
这里我只演示如何在Mybatis中实现RBAC权限模型的查询
现在有四张表
CREATE TABLE `user`
(`username` varchar(50) NOT NULL,`password` varchar(200) NOT NULL,`name` varchar(50),PRIMARY KEY (`username`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;-- 创建角色表
CREATE TABLE `role`
(`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50),PRIMARY KEY (`id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;-- 创建用户角色表
CREATE TABLE `user_role`
(`username` varchar(50),`role_id` int(11),PRIMARY KEY (`username`, `role_id`),FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;-- 创建菜单表
CREATE TABLE `menu`
(`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50),`parent_id` int(11),PRIMARY KEY (`id`),FOREIGN KEY (`parent_id`) REFERENCES `menu` (`id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;-- 创建角色菜单表
CREATE TABLE `role_menu`
(`role_id` int(11),`menu_id` int(11),PRIMARY KEY (`role_id`, `menu_id`),FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),FOREIGN KEY (`menu_id`) REFERENCES `menu` (`id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;# ------------------------------------------------------------------------- 插入用户数据
INSERT INTO user (username, password, name) VALUES ('user1', 'password1', 'User 1');
INSERT INTO user (username, password, name) VALUES ('user2', 'password2', 'User 2');-- 插入角色数据
INSERT INTO role (name) VALUES ('file_role');
INSERT INTO role (name) VALUES ('db_role');-- 插入用户角色数据
INSERT INTO user_role (username, role_id) VALUES ('user1', 1);
INSERT INTO user_role (username, role_id) VALUES ('user2', 2);-- 插入菜单数据
INSERT INTO menu (name, parent_id) VALUES ('File', NULL);
INSERT INTO menu (name, parent_id) VALUES ('Database', NULL);
INSERT INTO menu (name, parent_id) VALUES ('File Access', 1);
INSERT INTO menu (name, parent_id) VALUES ('Database Access', 2);-- 插入角色菜单数据
INSERT INTO role_menu (role_id, menu_id) VALUES (1, 3);
INSERT INTO role_menu (role_id, menu_id) VALUES (2, 4);

根据表分析,其实具有对应实体类的表只有user用户表和menu菜单表,其他的表都是用来关联和描述关系的,所以实体类只需要User和Menu
准备实体类User、Menu
@Data
public class User {private String username;private String password;private String name;private Menu menu;//一个用户只有一个菜单
}
//-------------------------------------------------
@Data
public class Menu {private Integer id;private String name;private Integer parentId;private List<Menu> sonMenus;//一个父级菜单下可能有多个子菜单
}
准备userMapper接口
public interface UserMapper {// 使用mybatis完成任意用户拥有的菜单查询List<User> getUsers();//使用mybatis的级联查询完成菜单的查询(包含子菜单)List<User> getUsersInclude();
}
准备userMapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.cnmd.mapper.UserMapper"><resultMap id="map1" type="user"><result property="username" column="username"/><result property="name" column="name"/><association property="menu" javaType="menu"><id property="id" column="menuId"/><result property="name" column="menuName"/><result property="parentId" column="menuParentId"/></association></resultMap><!--任意用户拥有的菜单查询--><select id="getUsers" resultMap="map1">SELECT u.username, u.name, m.name menuName, m.id menuId, m.parent_id menuParentIdFROM rbac.user uJOIN rbac.user_role ur ON u.username = ur.usernameJOIN rbac.role r ON ur.role_id = r.idJOIN rbac.role_menu rm ON r.id = rm.role_idJOIN rbac.menu m ON rm.menu_id = m.id;</select><!-- ================================================================ --><resultMap id="map2" type="user"><result property="username" column="username"/><result property="name" column="name"/><association property="menu" javaType="menu"><result property="name" column="parent_menu_name"/><collection property="sonMenus" ofType="menu"><result property="name" column="son_menu_name"/></collection></association></resultMap><!--完成菜单的查询(包含子菜单)--><select id="getUsersInclude" resultMap="map2">SELECT u.username, u.name, mp.name as parent_menu_name, m.name as son_menu_nameFROM rbac.user uJOIN rbac.user_role ur ON u.username = ur.usernameJOIN rbac.role r ON ur.role_id = r.idJOIN rbac.role_menu rm ON r.id = rm.role_idJOIN rbac.menu m ON rm.menu_id = m.idJOIN rbac.menu mp ON m.parent_id = mp.id;</select></mapper>
Java代码
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);List<User> users = mapper.getUsers();
users.forEach(System.out::println);System.out.println("====================================");List<User> usersInclude = mapper.getUsersInclude();
usersInclude.forEach(System.out::println);
查询结果
User(username=user1, password=null, name=User 1, menu=Menu(id=3, name=File Access, parentId=1, sonMenus=null))
User(username=user2, password=null, name=User 2, menu=Menu(id=4, name=Database Access, parentId=2, sonMenus=null))====================================User(username=user1, password=null, name=User 1, menu=Menu(id=null, name=File, parentId=null, sonMenus=[Menu(id=null, name=File Access, parentId=null, sonMenus=null)]))
User(username=user2, password=null, name=User 2, menu=Menu(id=null, name=Database, parentId=null, sonMenus=[Menu(id=null, name=Database Access, parentId=null, sonMenus=null)]))
如果需要单独完成菜单的查询(包含子菜单)
只需要重新创建MenuMapper接口
public interface MenuMapper {List<Menu> getMenus();
}
创建MenuMapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.cnmd.mapper.MenuMapper"><resultMap id="map" type="menu"><id property="id" column="parent_menu_id"/><result property="name" column="parent_menu_name"/><collection property="sonMenus" ofType="menu"><id property="id" column="son_menu_id"/><result property="name" column="son_menu_name"/></collection></resultMap><select id="getMenus" resultMap="map">SELECT m.id parent_menu_id, m.name as parent_menu_name, ms.id son_menu_id, ms.name as son_menu_nameFROM rbac.menu mJOIN rbac.menu msON m.id = ms.parent_id;</select></mapper>
查询结果
Menu(id=1, name=File, parentId=null, sonMenus=[Menu(id=3, name=File Access, parentId=null, sonMenus=null)])
Menu(id=2, name=Database, parentId=null, sonMenus=[Menu(id=4, name=Database Access, parentId=null, sonMenus=null)])
相关文章:
Mybatis实现RBAC权限模型查询
RBAC权限模型 Role-Based Access Control,中文意思是:基于角色(Role)的访问控制。这是一种广泛应用于计算机系统和网络安全领域的访问控制模型。 简单来说,就是通过将权限分配给➡角色,再将角色分配给➡用…...
最短路算法——差分约束
差分约束 (1) 求不等式组的可行解 源点:从源点出发,一定可以走到所有的边求可行解步骤: 先将每个不等式 x i ≤ x j c x_i \le x_j c xi≤xjc,转化成一条从 s j s_j sj走到 s i s_i si,长度为 c k c_k ck 的一条边找…...
Log4j日志框架讲解(全面,详细)
目录 Log4j概述 log4j的架构(组成) Loggers Appenders Layouts 快速入门 依赖 java代码 日志的级别 log4j.properties 自定义Logger 总结: Log4j概述 Log4j是Apache下的一款开源的日志框架,通过在项目中使用 Log4J&…...
LeetCode 35, 242, 994
目录 35. 搜索插入位置题目链接标签思路代码 242. 有效的字母异位词题目链接标签思路代码 994. 腐烂的橘子题目链接标签思路代码 35. 搜索插入位置 题目链接 35. 搜索插入位置 标签 数组 二分查找 思路 本题与 704. 二分查找 十分相似,只不过本题在找不到 tar…...
ctfshow-web入门-文件包含(web87)巧用 php://filter 流绕过死亡函数的三种方法
目录 方法1:php://filter 流的 base64-decode 方法 方法2:通过 rot13 编码实现绕过 方法3:通过 strip_tags 函数去除 XML 标签 除了替换,新增 file_put_contents 函数,将会往 $file 里写入 <?php die(大佬别秀了…...
adb shell ps -T打印出来参数的含义,以及D,T,Z代表的状态含义是什么?
在Android系统中,使用adb shell ps命令可以查看当前系统中运行的进程信息。当你添加-T选项时(注意,标准的ps命令在Android的adb shell中可能不直接支持-T选项,这通常与Linux中的ps命令略有不同),你可能是想…...
leetcode77组合——经典回溯算法
本文主要讲解组合的要点与细节,以及回溯算法的解题步骤,按照步骤思考更方便理解 c和java代码如下,末尾 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 具体要点: …...
springcloud-alibba之FeignClient
代码地址:springcloud系列: springcloud 组件分析拆解 1.FeignClient的集成 springboot版本:3.1.5 springcloud组件版本:2022.0.4 nacos客户端的版本:2.3.2 1.引pom 这里引入了nacos和feginclient的版本 <dependency>…...
三、docker配置阿里云镜像仓库并配置docker代理
一、配置阿里云镜像仓库 1. 登录阿里云官网,并登录 https://www.aliyun.com/ 2. 点击产品 - 容器 - 容器与镜像服务ACR - 管理控制台 - 镜像工具 - 镜像加速器 二、配置docker代理 #1. 创建docker相关的systemd文件 mkdir -p /etc/systemd/system/docker.servic…...
【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十一)-git(3)
Git是目前最流行的版本控制系统之一,在现代软件开发中扮演着重要的角色。它能够有效地跟踪文件变化、协作开发,并存储项目的历史记录。本文的目的是向读者介绍Git的基本概念和工作原理,帮助初学者快速上手使用Git,并帮助有经验的开…...
全面解析 TypeScript 泛型的二三事
2024年了相信大家都已经在日常开发的过程中使用上了 TypeScript 了。TypeScript 增强了代码可靠性和可维护性,确保减少运行时错误并提高开发人员的工作效率。 TypeScript 通过类型声明 使得 javascript 拥有了强类型校验。而泛型的是类型声明中最重要的一环&#x…...
单/多线程--协程--异步爬虫
免责声明:本文仅做技术交流与学习... 目录 了解进程和线程 单个线程(主线程)在执行 多线程 线程池 协程(爬虫多用) 假异步:(同步) 真异步: 爬虫代码模版 异步-爬虫 同步效果--19秒 异步效果--7秒 了解进程和线程 # --------------------> # ------> # …...
android pdf框架-11,查看图片
前10篇文章,9章关于pdf的,pdf解析后,里面也是有各种图片,于是利用pdf的view来展示图片,似乎也是个不错的想法. android手机中的图片查看功能,有的可以展示,有的不能.比如华为,荣耀对大体积的png是可以显示的,小米是不显示,只有缩略图. 一张png50m大,比如清明上河图,原图是tif…...
【CSS】深入浅出弹性布局
CSS的弹性布局(Flexbox)是一种用于在容器中沿着一维方向(水平或垂直)来布局、对齐和分配容器内项目空间的有效方式。它旨在提供一个更加有效的方式来布局、对齐和分配容器中项目的空间,即使它们的大小未知或是动态变化…...
医院挂号系统小程序的设计
管理员账户功能包括:系统首页,个人中心,患者管理,医生管理,专家信息管理,科室管理,预约信息管理,系统管理 微信端账号功能包括:系统首页,专家信息࿰…...
广州外贸建站模板
Yamal外贸独立站wordpress主题 绿色的亚马尔Yamal外贸独立站wordpress模板,适用于外贸公司建独立站的wordpress主题。 https://www.jianzhanpress.com/?p7066 赛斯科Sesko-W外贸建站WP主题 适合机械设备生产厂家出海做外贸官网的wordpress主题,红橙色…...
KDP数据分析实战:从0到1完成数据实时采集处理到可视化
智领云自主研发的开源轻量级Kubernetes数据平台,即Kubernetes Data Platform (简称KDP),能够为用户提供在Kubernetes上的一站式云原生数据集成与开发平台。在最新的v1.1.0版本中,用户可借助 KDP 平台上开箱即用的 Airflow、AirByte、Flink、K…...
【人工智能】-- 智能机器人
个人主页:欢迎来到 Papicatch的博客 课设专栏 :学生成绩管理系统 专业知识专栏: 专业知识 文章目录 🍉引言 🍉机器人介绍 🍈机器人硬件 🍍机械结构 🍍传感器 🍍控…...
Android广播机制
简介 某个网络的IP范围是192.168.0.XXX,子网 掩码是255.255.255.0,那么这个网络的广播地址就是192.168.0.255。广播数据包会被发送到同一 网络上的所有端口,这样在该网络中的每台主机都将会收到这条广播。为了便于进行系统级别的消息通知&…...
SQL FOREIGN KEY
SQL FOREIGN KEY 简介 SQL(Structured Query Language)是用于管理关系数据库管理系统(RDBMS)的标准编程语言。在SQL中,FOREIGN KEY是一个重要的概念,用于建立和维护数据库中不同表之间的关系。本文将详细介绍SQL FOREIGN KEY的概念、用途、以及如何在SQL中实现和使用FO…...
FreeRtos——24、STM32中断处理体系及软件定时器按键消抖
第一节:STM32中断处理体系结构1.中断处理路径:2.NVIC中断控制器的中断优先级:2.1 中断号:在NVIC中对于硬件产生的任何一个中断都分配了一个中断号,中断号是一个唯一的标识符,用于识别每个外设设备的中断。NVIC使用中断号来配置中断…...
GLM-5.1 全面支持与 Gemini CLI 集成:HagiCode 的多模型进化之路
GLM-5.1 全面支持与 Gemini CLI 集成:HagiCode 的多模型进化之路 本文介绍了 HagiCode 平台近期的重要更新——智谱 AI GLM-5.1 模型的全面支持,以及 Gemini CLI 作为第十个 Agent CLI 的成功集成。这两项更新进一步强化了平台的多模型能力和多 CLI 生态…...
springboot+vue基于web的宠物商城领养网站的设计与实现
目录同行可拿货,招校园代理 ,本人源头供货商功能模块分析技术实现要点特色功能扩展安全与性能项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 功能模块分析 用户模块 注册与登录&#…...
Hunyuan-MT-7B与SpringBoot整合实战:企业级翻译服务开发
Hunyuan-MT-7B与SpringBoot整合实战:企业级翻译服务开发 1. 引言 在全球化业务快速发展的今天,企业经常需要处理多语言内容。传统翻译方案要么成本高昂,要么响应速度慢,很难满足实时业务需求。腾讯开源的Hunyuan-MT-7B翻译模型&…...
res-downloader:智能资源捕获工具的技术实现与高效工作流指南
res-downloader:智能资源捕获工具的技术实现与高效工作流指南 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 资源…...
2026年Win11强力清理工具推荐:安全无广告的C盘瘦身软件怎么选?
我是个学生党,笔记本电脑的C盘从买回来就没清理过,最近装新游戏时直接提示空间不足。网上搜“Win11强力清理工具推荐”,跳出来一堆软件,看着都挺好,但又怕下载到带捆绑、弹广告的流氓软件。我只是想要一个能真正把C盘腾…...
Port-Hamiltonian建模在ROS2中的实战:用Python实现双机器人能量交换仿真
Port-Hamiltonian建模在ROS2中的实战:用Python实现双机器人能量交换仿真 当两个机器人在协作搬运物体时,它们的能量如何通过接触点传递?当一群无人机编队飞行时,如何数学描述它们之间无形的能量交互?这正是Port-Hamilt…...
TinyCheck开发指南:从源码结构到核心类设计,理解网络安全检测平台架构
TinyCheck开发指南:从源码结构到核心类设计,理解网络安全检测平台架构 【免费下载链接】TinyCheck TinyCheck allows you to easily capture network communications from a smartphone or any device which can be associated to a Wi-Fi access point …...
双目立体视觉实战:从平行视图到3D电影原理的完整解析
双目立体视觉实战:从平行视图到3D电影原理的完整解析 你是否曾在电影院戴上3D眼镜,被扑面而来的立体效果震撼?这种身临其境的视觉体验,其核心技术正是源于双目立体视觉原理。本文将带你深入探索从平行视图构建到3D电影实现的完整技…...
JPom结合Docker实现SpringBoot项目自动化构建与部署实战
1. 为什么你需要JPomDocker自动化部署方案 每次手动打包SpringBoot项目时,你是不是也经历过这样的痛苦?先在本地mvn clean package,然后scp上传到服务器,接着ssh连上去kill旧进程,最后nohup启动新jar包。更可怕的是半夜…...
