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);

image-20240705093050802
根据表分析,其实具有对应实体类的表只有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)])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/867099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

应急响应-网站入侵篡改指南Webshell内存马查杀漏洞排查时间分析

查看146天的内存马 方法&#xff1a; 1. 日志 这种地址一般在扫描 还要注意post传参注入 对其进行全局定位 发现有sql注入 我们可以也尝试去sqlmap注入 如果以这种方式注入ua头就会改变 2. 了解自己的中间件&#xff0c;框架&#xff0c;cve&#xff0c;等 因为不知道时间…

Unity中TimeLine的一些用法

Unity中TimeLine的一些用法 概念其他 概念 无Track模式&#xff08;PlayableAsset、PlayableBehaviour&#xff09; 1. 两者关系 运行在PlayableTrack中作用 PlayableBehaviour 实际执行的脚本字段并不会显示在timeline面板上 PlayableAsset PlayableBehaviour的包装器&#x…

[AI Perplexica] 安装指南:轻松部署AI驱动的开源搜索引擎

[AI Perplexica] AI驱动的开源搜索引擎[AI Perplexica] 深入解析&#xff0c;AI 架构揭秘 之前&#xff0c;我们看过了 Perplexica 的介绍&#xff0c;特点和架构&#xff0c;了解了其工作原理。 今天&#xff0c;我们一起来部署下 安装 docker 安装 docker https://docs.…

设计模式探索:代理模式

1. 什么是代理模式 定义 代理模式是一种结构型设计模式&#xff0c;通过为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和实际对象之间起到中介作用&#xff0c;可以在不改变真实对象的情况下增强或控制对真实对象的访问。 目的 代理模式的主要目的是隐…

【IT领域新生必看】Java编程中的神奇对比:深入理解`equals`与`==`的区别

文章目录 引言什么是操作符&#xff1f;基本数据类型的比较示例&#xff1a; 引用类型的比较示例&#xff1a; 什么是equals方法&#xff1f;equals方法的默认实现示例&#xff1a; 重写equals方法示例&#xff1a; equals与的区别比较内容不同示例&#xff1a; 使用场景不同示…

linux程序安装-编译-rpm-yum

编译安装流程步骤详解 识途老码 | Linux编译安装程序 编译安装概览 编译安装是从软件的源代码构建到最终安装的过程,它允许用户根据自身的需求和系统的环境来自定义软件的配置和功能。相对于二进制安装,编译安装提供了更高的灵活性和控制能力,但同时也要求用户具备一定的…

伯克利、斯坦福和CMU面向具身智能端到端操作联合发布开源通用机器人Policy,可支持多种机器人执行多种任务

不同于LLM或者MLLM那样用于上百亿甚至上千亿参数量的大模型&#xff0c;具身智能端到端大模型并不追求参数规模上的大&#xff0c;而是指其能吸收大量的数据&#xff0c;执行多种任务&#xff0c;并能具备一定的泛化能力&#xff0c;如笔者前博客里的RT1。目前该领域一个前沿工…

驱动开发系列 - pci驱动

一&#xff1a;pci驱动定义 #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/pci.h>MODULE_LICENSE("GPL");#define MY_VENDOR_ID 0xAAAA //厂家ID, PCI厂家ID在全球统一分配和管理 #defi…

linux19:程序替换

一&#xff1a;最简单的看看程序替换是什么样的&#xff08;单个进程版&#xff09; 1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 int main()5 {6 printf("Before : I am a process , myPid:%d,myPPid:%d\n",getpid(),getpp…

Java项目:基于SSM框架实现的德云社票务管理系统【ssm+B/S架构+源码+数据库+开题报告+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的德云社票务管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功…

windows下搭建python+jupyter notebook

一.下载python 下面网址下载python3 https://www.python.org/ 二. 安装jupyter notebook 三. 修改配置 四. 检测是否正常运行

JeeSite V5.7.1 发布,Java快速开发平台,Spring Boot,Vue3,微服务

升级内容 新增 IdGen.randomShortString() 方法&#xff0c;随机生成一个短字符串 新增 PropertiesUtils、Global 一些便捷方法&#xff0c;如果有设定属性值再执行某操作 新增 连接池 queryTimeout 查询超时时间、transactionQueryTimeout 事务超时时间参数 新增 Table 支持…

华为OD机试 - 跳马 - 广度优先搜索BFS(Java 2024 D卷 200分)

华为OD机试 2024D卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测…

windows 7 安装IPP协议,支持Internet打印

1 windows 7 安装IPP协议,支持Internet打印 #控制面板--打开或关闭Windows功能 3 复制Printers 文件夹 到 c:\inetpub\wwwroot\,复制msw3prt.dll到c:\windows\system32\ 4 打开IIs管理器 #报错:模块列表中不存在此处理程序所需的指定模块。如果您添加脚本映射处理程序映射&…

Golang | Leetcode Golang题解之第218题天际线问题

题目&#xff1a; 题解&#xff1a; type pair struct{ right, height int } type hp []pairfunc (h hp) Len() int { return len(h) } func (h hp) Less(i, j int) bool { return h[i].height > h[j].height } func (h hp) Swap(i, j int) { h[i], h[j]…

npm,yarn清楚缓存

1.运行以下命令来清理npm缓存&#xff1a; npm cache clean --force或者运行以下命令清理Yarn缓存&#xff1a; yarn cache clean2.删除 node_modules 和锁文件&#xff1a; 删除 node_modules 目录和 package-lock.json 或 yarn.lock 文件&#xff0c;然后重新安装依赖 rm …

【Android】自定义换肤框架02之自定义AssetManager和Resource

ResourceId是如何变成对应Resource的 在上一章中&#xff0c;我们已经讲过&#xff0c;apk中有个资源索引文件 其中保存了每个资源对应的id&#xff0c;name&#xff0c;type&#xff0c;path 资源文件的解析&#xff0c;主要涉及两个类&#xff0c;AssetManager和Resource …

独立开发者系列(20)——扫码登录

&#xff08;1&#xff09;网页端的安全登录设计 很多大型网站都有登录限制。这里以一个案例作为例子完整解析。理解安全的登录设计方式&#xff0c;无论对于以后做自动化&#xff0c;自动登录网站&#xff0c;获取数据&#xff0c;还是自己开发月租类型的系统非常有用。当前一…

算法力扣刷题 三十三【347.前 K 个高频元素】

前言 栈和队列篇。 记录 三十三【347.前 K 个高频元素】 一、题目阅读 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2]示例 2: 输入: nums [1]…

从草图到现实:SketchUp 在建筑项目中的独特优势

Sketchup 是全球最受欢迎的建筑可视化平台之一。借助该平台提供的各种工具&#xff0c;您可以创建可供市场使用的逼真项目。Sketchup为什么如此优秀&#xff1f;它对建筑项目有哪些优势&#xff1f;下面&#xff0c;你将看到什么是 Sketchup 以及这个工具的一些重要的优势。 关…