SSM - Springboot - MyBatis-Plus 全栈体系(十六)
第三章 MyBatis
三、MyBatis 多表映射
2. 对一映射
2.1 需求说明
- 根据 ID 查询订单,以及订单关联的用户的信息!
2.2 OrderMapper 接口
public interface OrderMapper {Order selectOrderWithCustomer(Integer orderId);
}
2.3 OrderMapper.xml 配置文件
<!-- 创建resultMap实现“对一”关联关系映射 -->
<!-- id属性:通常设置为这个resultMap所服务的那条SQL语句的id加上“ResultMap” -->
<!-- type属性:要设置为这个resultMap所服务的那条SQL语句最终要返回的类型 -->
<resultMap id="selectOrderWithCustomerResultMap" type="order"><!-- 先设置Order自身属性和字段的对应关系 --><id column="order_id" property="orderId"/><result column="order_name" property="orderName"/><!-- 使用association标签配置“对一”关联关系 --><!-- property属性:在Order类中对一的一端进行引用时使用的属性名 --><!-- javaType属性:一的一端类的全类名 --><association property="customer" javaType="customer"><!-- 配置Customer类的属性和字段名之间的对应关系 --><id column="customer_id" property="customerId"/><result column="customer_name" property="customerName"/></association></resultMap><!-- Order selectOrderWithCustomer(Integer orderId); -->
<select id="selectOrderWithCustomer" resultMap="selectOrderWithCustomerResultMap">SELECT order_id,order_name,c.customer_id,customer_nameFROM t_order oLEFT JOIN t_customer cON o.customer_id=c.customer_idWHERE o.order_id=#{orderId}</select>
- 对应关系可以参考下图:

2.4 Mybatis 全局注册 Mapper 文件
<!-- 注册Mapper配置文件:告诉Mybatis我们的Mapper配置文件的位置 -->
<mappers><!-- 在mapper标签的resource属性中指定Mapper配置文件以“类路径根目录”为基准的相对路径 --><mapper resource="mappers/OrderMapper.xml"/></mappers>
2.5 junit 测试程序
@Slf4j
public class MyBatisTest {private SqlSession session;// junit会在每一个@Test方法前执行@BeforeEach方法@BeforeEachpublic void init() throws IOException {session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")).openSession();}@Testpublic void testRelationshipToOne() {OrderMapper orderMapper = session.getMapper(OrderMapper.class);// 查询Order对象,检查是否同时查询了关联的Customer对象Order order = orderMapper.selectOrderWithCustomer(2);log.info("order = " + order);}// junit会在每一个@Test方法后执行@@AfterEach方法@AfterEachpublic void clear() {session.commit();session.close();}
}
2.6 关键词
- 在“对一”关联关系中,我们的配置比较多,但是关键词就只有:association 和 javaType
3. 对多映射
3.1 需求说明
- 查询客户和客户关联的订单信息!
3.2 CustomerMapper 接口
public interface CustomerMapper {Customer selectCustomerWithOrderList(Integer customerId);}
3.3 CustomerMapper.xml 文件
<!-- 配置resultMap实现从Customer到OrderList的“对多”关联关系 -->
<resultMap id="selectCustomerWithOrderListResultMap"type="customer"><!-- 映射Customer本身的属性 --><id column="customer_id" property="customerId"/><result column="customer_name" property="customerName"/><!-- collection标签:映射“对多”的关联关系 --><!-- property属性:在Customer类中,关联“多”的一端的属性名 --><!-- ofType属性:集合属性中元素的类型 --><collection property="orderList" ofType="order"><!-- 映射Order的属性 --><id column="order_id" property="orderId"/><result column="order_name" property="orderName"/></collection></resultMap><!-- Customer selectCustomerWithOrderList(Integer customerId); -->
<select id="selectCustomerWithOrderList" resultMap="selectCustomerWithOrderListResultMap">SELECT c.customer_id,c.customer_name,o.order_id,o.order_nameFROM t_customer cLEFT JOIN t_order oON c.customer_id=o.customer_idWHERE c.customer_id=#{customerId}
</select>
- 对应关系可以参考下图:

3.4 Mybatis 全局注册 Mapper 文件
<!-- 注册Mapper配置文件:告诉Mybatis我们的Mapper配置文件的位置 -->
<mappers><!-- 在mapper标签的resource属性中指定Mapper配置文件以“类路径根目录”为基准的相对路径 --><mapper resource="mappers/OrderMapper.xml"/><mapper resource="mappers/CustomerMapper.xml"/>
</mappers>
3.5 junit 测试程序
@Test
public void testRelationshipToMulti() {CustomerMapper customerMapper = session.getMapper(CustomerMapper.class);// 查询Customer对象同时将关联的Order集合查询出来Customer customer = customerMapper.selectCustomerWithOrderList(1);log.info("customer.getCustomerId() = " + customer.getCustomerId());log.info("customer.getCustomerName() = " + customer.getCustomerName());List<Order> orderList = customer.getOrderList();for (Order order : orderList) {log.info("order = " + order);}
}
3.6 关键词
- 在“对多”关联关系中,同样有很多配置,但是提炼出来最关键的就是:“collection”和“ofType”
4. 多表映射总结
4.1 多表映射优化
| setting 属性 | 属性含义 | 可选值 | 默认值 |
|---|---|---|---|
| autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。 | NONE, PARTIAL, FULL | PARTIAL |
-
我们可以将 autoMappingBehavior 设置为 full,进行多表 resultMap 映射的时候,可以省略符合列和属性命名映射规则(列名=属性名,或者开启驼峰映射也可以自定映射)的 result 标签!
-
修改 mybatis-sconfig.xml:
<!--开启resultMap自动映射 -->
<setting name="autoMappingBehavior" value="FULL"/>
- 修改 teacherMapper.xml
<resultMap id="teacherMap" type="teacher"><id property="tId" column="t_id" /><!-- 开启自动映射,并且开启驼峰式支持!可以省略 result!-->
<!-- <result property="tName" column="t_name" />--><collection property="students" ofType="student" ><id property="sId" column="s_id" />
<!-- <result property="sName" column="s_name" />--></collection>
</resultMap>
4.2 多表映射总结
| 关联关系 | 配置项关键词 | 所在配置文件和具体位置 |
|---|---|---|
| 对一 | association 标签/javaType 属性/property 属性 | Mapper 配置文件中的 resultMap 标签内 |
| 对多 | collection 标签/ofType 属性/property 属性 | Mapper 配置文件中的 resultMap 标签内 |
四、MyBatis 动态语句
1. 动态语句需求和简介
- 经常遇到很多按照很多查询条件进行查询的情况,比如智联招聘的职位搜索等。其中经常出现很多条件不取值的情况,在后台应该如何完成最终的 SQL 语句呢?

- 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
- 使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
- 如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
2. if 和 where 标签
- 使用动态 SQL 最常见情景是根据条件包含 where / if 子句的一部分。比如:
<!-- List<Employee> selectEmployeeByCondition(Employee employee); -->
<select id="selectEmployeeByCondition" resultType="employee">select emp_id,emp_name,emp_salary from t_emp<!-- where标签会自动去掉“标签体内前面多余的and/or” --><where><!-- 使用if标签,让我们可以有选择的加入SQL语句的片段。这个SQL语句片段是否要加入整个SQL语句,就看if标签判断的结果是否为true --><!-- 在if标签的test属性中,可以访问实体类的属性,不可以访问数据库表的字段 --><if test="empName != null"><!-- 在if标签内部,需要访问接口的参数时还是正常写#{} -->or emp_name=#{empName}</if><if test="empSalary > 2000">or emp_salary>#{empSalary}</if><!--第一种情况:所有条件都满足 WHERE emp_name=? or emp_salary>?第二种情况:部分条件满足 WHERE emp_salary>?第三种情况:所有条件都不满足 没有where子句--></where>
</select>
3. set 标签
<!-- void updateEmployeeDynamic(Employee employee) -->
<update id="updateEmployeeDynamic">update t_emp<!-- set emp_name=#{empName},emp_salary=#{empSalary} --><!-- 使用set标签动态管理set子句,并且动态去掉两端多余的逗号 --><set><if test="empName != null">emp_name=#{empName},</if><if test="empSalary < 3000">emp_salary=#{empSalary},</if></set>where emp_id=#{empId}<!--第一种情况:所有条件都满足 SET emp_name=?, emp_salary=?第二种情况:部分条件满足 SET emp_salary=?第三种情况:所有条件都不满足 update t_emp where emp_id=?没有set子句的update语句会导致SQL语法错误-->
</update>
4. trim 标签(了解)
-
使用 trim 标签控制条件部分两端是否包含某些字符
- prefix 属性:指定要动态添加的前缀
- suffix 属性:指定要动态添加的后缀
- prefixOverrides 属性:指定要动态去掉的前缀,使用“|”分隔有可能的多个值
- suffixOverrides 属性:指定要动态去掉的后缀,使用“|”分隔有可能的多个值
<!-- List<Employee> selectEmployeeByConditionByTrim(Employee employee) -->
<select id="selectEmployeeByConditionByTrim" resultType="com.atguigu.mybatis.entity.Employee">select emp_id,emp_name,emp_age,emp_salary,emp_genderfrom t_emp<!-- prefix属性指定要动态添加的前缀 --><!-- suffix属性指定要动态添加的后缀 --><!-- prefixOverrides属性指定要动态去掉的前缀,使用“|”分隔有可能的多个值 --><!-- suffixOverrides属性指定要动态去掉的后缀,使用“|”分隔有可能的多个值 --><!-- 当前例子用where标签实现更简洁,但是trim标签更灵活,可以用在任何有需要的地方 --><trim prefix="where" suffixOverrides="and|or"><if test="empName != null">emp_name=#{empName} and</if><if test="empSalary > 3000">emp_salary>#{empSalary} and</if><if test="empAge <= 20">emp_age=#{empAge} or</if><if test="empGender=='male'">emp_gender=#{empGender}</if></trim>
</select>
5. choose / when / otherwise 标签
-
在多个分支条件中,仅执行一个。
- 从上到下依次执行条件判断
- 遇到的第一个满足条件的分支会被采纳
- 被采纳分支后面的分支都将不被考虑
- 如果所有的 when 分支都不满足,那么就执行 otherwise 分支
<!-- List<Employee> selectEmployeeByConditionByChoose(Employee employee) -->
<select id="selectEmployeeByConditionByChoose" resultType="com.atguigu.mybatis.entity.Employee">select emp_id,emp_name,emp_salary from t_empwhere<choose><when test="empName != null">emp_name=#{empName}</when><when test="empSalary < 3000">emp_salary < 3000</when><otherwise>1=1</otherwise></choose><!--第一种情况:第一个when满足条件 where emp_name=?第二种情况:第二个when满足条件 where emp_salary < 3000第三种情况:两个when都不满足 where 1=1 执行了otherwise-->
</select>
6. foreach 标签
6.1 基本用法
- 用批量插入举例
<!--collection属性:要遍历的集合item属性:遍历集合的过程中能得到每一个具体对象,在item属性中设置一个名字,将来通过这个名字引用遍历出来的对象separator属性:指定当foreach标签的标签体重复拼接字符串时,各个标签体字符串之间的分隔符open属性:指定整个循环把字符串拼好后,字符串整体的前面要添加的字符串close属性:指定整个循环把字符串拼好后,字符串整体的后面要添加的字符串index属性:这里起一个名字,便于后面引用遍历List集合,这里能够得到List集合的索引值遍历Map集合,这里能够得到Map集合的key-->
<foreach collection="empList" item="emp" separator="," open="values" index="myIndex"><!-- 在foreach标签内部如果需要引用遍历得到的具体的一个对象,需要使用item属性声明的名称 -->(#{emp.empName},#{myIndex},#{emp.empSalary},#{emp.empGender})
</foreach>
6.2 批量更新时需要注意
- 上面批量插入的例子本质上是一条 SQL 语句,而实现批量更新则需要多条 SQL 语句拼起来,用分号分开。也就是一次性发送多条 SQL 语句让数据库执行。此时需要在数据库连接信息的 URL 地址中设置:
alex.dev.url=jdbc:mysql:///mybatis-example?allowMultiQueries=true
- 对应的 foreach 标签如下:
<!-- int updateEmployeeBatch(@Param("empList") List<Employee> empList) -->
<update id="updateEmployeeBatch"><foreach collection="empList" item="emp" separator=";">update t_emp set emp_name=#{emp.empName} where emp_id=#{emp.empId}</foreach>
</update>
6.3 关于 foreach 标签的 collection 属性
- 如果没有给接口中 List 类型的参数使用@Param 注解指定一个具体的名字,那么在 collection 属性中默认可以使用 collection 或 list 来引用这个 list 集合。这一点可以通过异常信息看出来:
Parameter 'empList' not found. Available parameters are [arg0, collection, list]
- 在实际开发中,为了避免隐晦的表达造成一定的误会,建议使用@Param 注解明确声明变量的名称,然后在 foreach 标签的 collection 属性中按照@Param 注解指定的名称来引用传入的参数。
7. sql 片段
7.1 抽取重复的 SQL 片段
<!-- 使用sql标签抽取重复出现的SQL片段 -->
<sql id="mySelectSql">select emp_id,emp_name,emp_age,emp_salary,emp_gender from t_emp
</sql>
7.2 引用已抽取的 SQL 片段
<!-- 使用include标签引用声明的SQL片段 -->
<include refid="mySelectSql"/>
相关文章:
SSM - Springboot - MyBatis-Plus 全栈体系(十六)
第三章 MyBatis 三、MyBatis 多表映射 2. 对一映射 2.1 需求说明 根据 ID 查询订单,以及订单关联的用户的信息! 2.2 OrderMapper 接口 public interface OrderMapper {Order selectOrderWithCustomer(Integer orderId); }2.3 OrderMapper.xml 配置…...
k8s--storageClass自动创建PV
文章目录 一、storageClass自动创建PV1.1 安装NFS1.2 创建nfs storageClass1.3 测试自动创建pv 一、storageClass自动创建PV 这里使用NFS实现 1.1 安装NFS 安装nfs-server: sh nfs_install.sh /mnt/data03 10.60.41.0/24nfs_install.sh #!/bin/bash### How to i…...
7.3 调用函数
前言: 思维导图: 7.3.1 函数调用的形式 我的笔记: 函数调用的形式 在C语言中,调用函数是一种常见的操作,主要有以下几种调用方式: 1. 函数调用语句 此时,函数调用独立存在,作为…...
如果使用pprof来进行性能的观测和优化
1. 分析性能瓶颈 在开始优化之前,首先需要确定你的程序的性能瓶颈在哪里。使用性能分析工具(例如 Go 的内置 pprof 包)来检测程序中消耗时间和内存的地方。这可以帮助你确定需要优化的具体部分。 2. 选择适当的数据结构和算法 选择正确的数…...
在移动固态硬盘上安装Ubuntu系统和ROS2
目录 原视频准备烧录 原视频 b站鱼香ros 准备 1.在某宝上买一个usb移动固态硬盘或固态U盘,至少64G 2.下载鱼香ros烧录工具 下载第二个就行了,不然某网盘的速度下载全部要一天 下载后,选择FishROS2OS制作工具压缩包,进行解压…...
【iptables 实战】02 iptables常用命令
一、iptables中基本的命令参数 -P 设置默认策略-F 清空规则链-L 查看规则链-A 在规则链的末尾加入新规则-I num 在规则链的头部加入新规则-D num 删除某一条规则-s 匹配来源地址IP/MASK,加叹号“!”表示除这个IP外-d 匹配目标地址-i 网卡名称 匹配从这块…...
webview_flutter
查看webview内核 https://liulanmi.com/labs/core.html h5中获取设备 https://cloud.tencent.com/developer/ask/sof/105938013 https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/mediaDevices web资源部署后navigator获取不到mediaDevices实例的解决方案&…...
【GESP考级C++】1级样题 闰年统计
GSEP 1级样题 闰年统计 题目描述 小明刚刚学习了如何判断平年和闰年,他想知道两个年份之间(包含起始年份和终止年份)有几个闰年。你能帮帮他吗? 输入格式 输入一行,包含两个整数,分别表示起始年份和终止…...
CentOS密码重置
背景: 我有一个CentOS虚拟机,但是密码忘记了,偶尔记起可以重置密码,于是今天尝试记录一下,又因为我最近记性比较差,所以必须要记录一下。 过程: 1、在引导菜单界面(grubÿ…...
Tomcat Servlet
Tomcat & Servlet 一、What is “Tomcat”?二、 What is “Servlet”?1、HttpServlet2、HttpServletRequest3、HttpServletResponse 一、What is “Tomcat”? Tomcat 本质上是一个基于 TCP 协议的 HTTP 服务器。我们知道HTTP是一种应用层协议,是 HTTP 客户端…...
国庆day2---select实现服务器并发
select.c: #include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__:",__LINE__);\perror(msg);\ }while(0)#define IP "192.168.1.3" #define PORT 8888int main(int argc, const char *argv[]) {//创建报式套接字socketi…...
Grafana 开源了一款 eBPF 采集器 Beyla
eBPF 的发展如火如荼,在可观测性领域大放异彩,Grafana 近期也发布了一款 eBPF 采集器,可以采集服务的 RED 指标,本文做一个尝鲜介绍,让读者有个大概了解。 eBPF 基础介绍可以参考我之前的文章《eBPF Hello world》。理…...
亲测可用国产GPT人工智能
分享一些靠谱、可用、可以白嫖的GPT大模型。配合大模型,工作效率都会极大提升。 清华大学ChatGLM 官网: 智谱清言中国版对话语言模型,与GLM大模型进行对话。https://chatglm.cn/开源的、支持中英双语的1300亿参数的对话语言模型࿰…...
适配器模式详解和实现(设计模式 四)
适配器模式将一个类的接口转换成客户端所期望的另一个接口,解决由于接口不兼容而无法进行合作的问题。 设计基本步骤 1. 创建目标接口(Target Interface),该接口定义了客户端所期望的方法。 2.创建被适配类(Adaptee…...
IDEA的使用
文章目录 1.IDEA配置1.1 idea界面说明1.2 git1.3 JDK1.4 maven1.5 Tomcat1.6 idea设置编码格式1.7 vscodenodejs1.8 windows下安装redis 2. IDEA问题2.1 setAttribute方法爆红2.2 idea cannot download sources解决办法2.3 springboot项目跑起来不停run 3. vscode3.1 vscode显示…...
CSS详细基础(二)文本样式
插播一条CSS的工作原理: CSS是一种定义样式结构如字体、颜色、位置等的语言,被用于描述网页上的信息格式化和显示的方式。CSS样式可以直接存储于HTML网页或者单独的样式单文件。无论哪一种方式,样式单包含将样式应用到指定类型的元素的规则。…...
win10系统任务栏图标变成白色的解决办法
我平时都是用滴答清单进行管理这个自己的日程代办的,但是今天打开的时候发现这个快捷方式突然变成纯白色的了,重启电脑之后,这个图标的样式仍然没有变化。上网查找解决办法之后,终于搞好了,于是就有了下面的教程。 为什…...
hadoop生态现状、介绍、部署
一、引出hadoop 1、hadoop的高薪现状 各招聘平台都有许多hadoop高薪职位,可以看看职位所需求的技能 ----> hadoop是什么,为什么会这么高薪?引出大数据,大数据时代,大数据与云计算 2、大数据时代的介绍 大数据的故事…...
二、EFCore 数据库表的创建和迁移
文章目录 一、数据库连接二、数据库表迁移一、数据库连接 在NuGet上安装EntityFramework 代码如下: Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore.SqlServerMicrosoft.Extensions.Configuration.Json配置数据连接 appsettings.json 增加数据库连接配置 &quo…...
在nodejs中使用typescript
在nodejs中使用typescript 如果我们正在使用nodejs来开发应用,那么对于管理和扩展一个大型代码库来说是一个非常大的挑战。克服这一问题的方法之一是使用typescript,为js添加可选的类型注释和高级功能。在本文中,我们将探讨如何使用在nodejs中使用types…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...
Django RBAC项目后端实战 - 03 DRF权限控制实现
项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...
