Mybatis实现RBAC权限模型查询

news2024/11/19 6:36:41

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 = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- 创建角色表
CREATE TABLE `role`
(
    `id`   int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(50),
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  DEFAULT 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 = InnoDB
  DEFAULT 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 = InnoDB
  DEFAULT 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 = InnoDB
  DEFAULT 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 mapper
		PUBLIC "-//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 menuParentId
		FROM rbac.user u
				 JOIN rbac.user_role ur ON u.username = ur.username
				 JOIN rbac.role r ON ur.role_id = r.id
				 JOIN rbac.role_menu rm ON r.id = rm.role_id
				 JOIN 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_name
		FROM rbac.user u
				 JOIN rbac.user_role ur ON u.username = ur.username
				 JOIN rbac.role r ON ur.role_id = r.id
				 JOIN rbac.role_menu rm ON r.id = rm.role_id
				 JOIN rbac.menu m ON rm.menu_id = m.id
				 JOIN 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 mapper
		PUBLIC "-//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_name
		FROM rbac.menu m
				 JOIN rbac.menu ms
					  ON 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.coloradmin.cn/o/1896500.html

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

相关文章

leetcode--二叉树中的最长交错路径

leetcode地址&#xff1a;二叉树中的最长交错路径 给你一棵以 root 为根的二叉树&#xff0c;二叉树中的交错路径定义如下&#xff1a; 选择二叉树中 任意 节点和一个方向&#xff08;左或者右&#xff09;。 如果前进方向为右&#xff0c;那么移动到当前节点的的右子节点&…

盘点AI做自媒体五条赚钱路径,新手小白必看(附教程)

前言 盘点用AI做自媒体赚钱的五条路径&#xff0c;只要学会使用AI工具&#xff0c;你也可以马上赚到钱。 我认为短视频是趋势&#xff0c;但相比于短视频而言&#xff0c;AI则是未来更大的趋势。 AI现在才属于萌芽期&#xff0c;好比是98年的互联网和07年的移动互联网&#x…

Jmeter使用JSON Extractor提取多个变量

1.当正则不好使时&#xff0c;用json extractor 2.提取多个值时&#xff0c;默认值必填&#xff0c;否则读不到变量

Linux - Shell 以及 权限问题

目录 Shell的运行原理 Linux权限问题 Linux权限的概念 如何实现用户账号之间的切换 如何仅提升当前指令的权限 如何将普通用户添加到信任列表 Linux权限管理 文件访问者的分类&#xff08;人&#xff09; 文件类型和访问权限&#xff08;事物属性&#xff09; 文件权限值的表…

【基于深度学习方法的激光雷达点云配准系列之GeoTransformer】——模型部分浅析(1)

【GeoTransformer系列】——模型部分 1. create_model2. model的本质3. 模型的主要结构3.1 backbone3.2 transformer本篇继续对GeoTransformer/experiments/geotransformer.kitti.stage5.gse.k3.max.oacl.stage2.sinkhorn/下面的trainval.py进行详细的解读,主要是模型部分, 可以…

一款针对Webpack等前端打包工具所构造的网站进行快速、高效安全检测的扫描工具

免责声明 由于传播、利用本公众号夜组安全所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;公众号夜组安全及作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担&#xff01;如有侵权烦请告知&#xff0c;我们会立即删除…

硅纪元视角 | 法国8人团队发布Moshi,挑战OpenAI的开源实时多模态模型!

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

51单片机-让一个LED灯闪烁、流水灯(涉及:自定义单片机的延迟时间)

目录 设置单片机的延迟&#xff08;睡眠&#xff09;函数查看单片机的时钟频率设置系统频率、定时长度、指令集 完整代码生成HEX文件下载HEX文件到单片机流水灯代码 (自定义延迟时间) 设置单片机的延迟&#xff08;睡眠&#xff09;函数 查看单片机的时钟频率 检测前单片机必…

红海云签约海新域集团,产业服务运营领军企业加速人力资源数字化转型

北京海新域城市更新集团有限公司&#xff08;以下简称“海新域集团”&#xff09;是北京市海淀国有资产投资集团有限公司一级监管企业&#xff0c;致力于成为国内领先的产业服务运营商。集团积极探索城市和产业升级新模式&#xff0c;通过对老旧、低效等空间载体重新定位规划、…

【Python】成功解决TypeError: iteration over a 0-d tensor

【&#x1f40d;Python】成功解决TypeError: iteration over a 0-d tensor 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xf…

赶快收藏!全网最佳websocket封装:完美支持断网重连、自动心跳!

简介 websocket在前端开发中,是一个必须掌握的技术!你可以不用,但必须掌握! 前几天,就遇到这样一个需求,要求界面的数据通过websocket实时推送,并且必须支持断网重连、自动心跳! 自动心跳是定期向服务端发送小型数据包,如果一段时间内服务端没有收到心跳响应,系统可…

大模型LLMs概述:利用大模型 (LLMs) 解决信息抽取任务

论文标题&#xff1a;Large Language Models for Generative Information Extraction: A Survey 论文链接&#xff1a;https://arxiv.org/pdf/2312.17617.pdf 论文主要探讨了大型语言模型&#xff08;LLMs&#xff09;在生成式信息抽取&#xff08;IE&#xff09;任务中的应用…

1.1.2数据结构的三要素

一.数据结构的三要素 数据结构这门课着重关注的是数据元素之间的关系&#xff0c;和对这些数据元素的操作&#xff0c;而不关心具体的数据项内容 。 1.逻辑结构 &#xff08;1&#xff09;集合结构 &#xff08;2&#xff09;线性结构 数据元素之间是一对一的关系。除了第一个…

【C语言】return 关键字

在C语言中&#xff0c;return是一个关键字&#xff0c;用于从函数中返回值或者结束函数的执行。它是函数的重要组成部分&#xff0c;负责将函数的计算结果返回给调用者&#xff0c;并可以提前终止函数的执行。 主要用途和原理&#xff1a; 返回值给调用者&#xff1a; 当函数执…

AI绘画Stable Diffusion画全身图总是人脸扭曲?ADetailer插件实现一键解决!

大家好&#xff0c;我是向阳 你是否遇到过SD生成的人物脸部扭曲、甚至令人恶心的情况&#xff1f;也曾感到束手无策&#xff1f;别担心&#xff0c;这份教程专为你而来。 在使用SD生成人物全身照时&#xff0c;你可能经常发现人物的脸部会出现扭曲问题。这是因为人物面部像素…

TP8/6 更改后台入口地址admin改为myadmin 隐藏真实后台网址

原来www.xxx.com/admin 改后www.xxx.com/myadmin config/app.php // 应用映射&#xff08;自动多应用模式有效&#xff09;app_map > [admintest>admin], 官方文档&#xff1a;ThinkPHP官方手册

免费申请 HTTPS 证书的八大方法

大家好,我是CodeQi! 一位热衷于技术分享的码仔。 为了保证网站的安全和数据的隐私性,使用 HTTPS 加密协议已成为必需。HTTPS 证书由受信任的证书颁发机构 (CA) 签发,可以加密客户端和服务器之间的通信。 幸运的是,有许多方法可以免费申请 HTTPS 证书。本文将介绍八种方法…

云仓酒庄天津分公司:深化业务常态化运营

标题&#xff1a;云仓酒庄天津分公司&#xff1a;深化业务常态化运营&#xff0c;以沙龙为纽带&#xff0c;构建价值叠加的酒业新生态 在当今复杂多变的经济环境中&#xff0c;传统酒业面临着前所未有的挑战与机遇。随着数字化转型的加速和消费者偏好的日益多元化&#xff0c;…

springcloud+vue项目,controller层接口返回json数据,前端可以接收到数据,但浏览器“F12-->网络-->响应“显示为空的问题处理

1.显示为空的场景 SharetekR(access_tokeneyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJQQzoxODA1ODA4ODc1MjUwMTIyNzUyIiwicm5TdHIiOiJrZEoxV05CV3NBSUdYb05TbktSU3kzOGNuSnk3c3FRTSIsInVzZXJJZCI6MTgwNTgwODg3NTI1MDEyMjc1MiwidXNlck5h…

【Python】九种数据类型详讲(内含常见常见的字符串函数汇总)

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言Number&#xff08;数字&#xff09;整数类型int &#xff08;整型&#xff0c;长整型&#xff09;float&#xff08;浮点型&#xff09;complex&#xff08;复数&#xff09;…