如何在MyBatis中处理复杂结果集映射关系

news2024/11/25 9:02:09

文章目录

  • 前言
  • 一、 准备工作
  • 二、resultMap处理字段和属性的映射关系
  • 三、多对一映射
    • 0、级联方式处理映射关系
    • 1、使用association处理映射关系
    • 2、分步查询解决多对一关系
      • (1) 查询员工信息
      • (2) 根据员工所对应的部门id查询部门信息
      • 延迟加载
  • 三、一对多的关系处理
    • 0、使用collection来维系一对多的关系
    • 1、分步查询
      • (1)查询部门信息
      • (2)根据部门id查询部门中的所有员工
      • (3)测试类

前言

在开发中,我们不是总是对单表进行操作的场景。按照数据库表的设计原则,要符合一定的范式,那么就需要对某一种场景的表进行拆分。
在业务上,可能是属于同一个业务。但是,在数据库中表的存储这块,可能就会涉及到表的拆分。
这里设计到表的创建直接创建两张表:

一、 准备工作

  1. 对于如何搭建MyBatis的测试环境,在博文从0到1搭建MyBatis实例思路剖析中有详细的介绍,这里就不一一的进行展开。
  2. MySQL数据库中创建两张表作为本次测试所需要的环境基础。
    在第一步的基础上,我们导入两张表。一张是t_dept,另一张是t_emp
    t_dept
DROP TABLE IF EXISTS `t_dept`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `t_dept` (
  `did` int NOT NULL,
  `dept_name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`did`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `t_dept`
--

LOCK TABLES `t_dept` WRITE;
/*!40000 ALTER TABLE `t_dept` DISABLE KEYS */;
INSERT INTO `t_dept` VALUES (1,'开发组'),(2,'ai组'),(3,'运维组');
/*!40000 ALTER TABLE `t_dept` ENABLE KEYS */;
UNLOCK TABLES;

t_emp表:

DROP TABLE IF EXISTS `t_emp`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `t_emp` (
  `eid` int NOT NULL,
  `emo_name` varchar(45) DEFAULT NULL,
  `age` int DEFAULT NULL,
  `sex` char(1) DEFAULT NULL,
  `email` varchar(45) DEFAULT NULL,
  `did` int DEFAULT NULL,
  PRIMARY KEY (`eid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `t_emp`
--

LOCK TABLES `t_emp` WRITE;
/*!40000 ALTER TABLE `t_emp` DISABLE KEYS */;
INSERT INTO `t_emp` VALUES (1,'lucy',23,'0','lucy@gmail.com',1),(2,'jack',24,'1','jack@gmail.com',1),(3,'smith',22,'1','smith@openai.com',2),(4,'zhangsan',46,'1','zhangsan@openai.com',2),(5,'limu',47,'1','limu@amazon.com',3),(6,'fong',23,'1','fong@amazon.com',3);
/*!40000 ALTER TABLE `t_emp` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

先大致看一下数据库中的数据:
在这里插入图片描述

  1. 建立mapper、pojo、映射文件
    整体的项目结构是:
    在这里插入图片描述
    mapper接口:
public interface DeptMapper {
}
public interface EmpMapper {
}

pojo:

// dept
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept{
    private Integer did;
    private String deptName;
}
// emp
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
    private Integer eid;
    private String empName;
    private Integer age;
    private String sex;
    private String email;
}

这里我直接使用lombok来动态的生成gettersetter方法
使用方法是直接在pom.xml文件中导入依赖

 <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.26</version>
    </dependency>

xxxMapper.xml

<!--DeptMapper.xml-->
<mapper namespace="com.fckey.mybatis.mapper.DeptMapper">
</mapper>
<!--EmpMapper.xml-->
<mapper namespace="com.fckey.mybatis.mapper.EmpMapper">
</mapper>

二、resultMap处理字段和属性的映射关系

若字段名和实体类中的属性名不一致,但是字段名和属性名通过驼峰规则可以可以进行转变的。或者是不能进行转变的。都有对应的处理方法。
下面这种就是符合驼峰规则的:
在这里插入图片描述
对于可以通过驼峰规则进行映射的,有一种特有的解决映射问题的方法,可以直接在mybatis-config.xml全局配置文件中配置mapUnderscoreToCamelCase支持这种关系的映射

 <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

还有更加通用的方法解决映射问题:

  1. 给所有查出的字段起一个别名
<!--    List<Emp> getAll();-->
    <select id="getAll" resultType="emp">
        select eid, emp_name empName, age, sex, email from t_emp
    </select>

  1. 自定义resultmap来定义映射规则
    resultMap中,一一对应地设置属性名->字段名,再在select标签中添加resultMap="对应resultMap的id"
<!--
        resultMap设置自定义映射关系
        id      唯一标识
        type    映射的实体类型

        子标签:id 设置主键的映射关系, result设置其他的映射关系
            property    设置映射关系中的属性名,必须是type属性所设置的实体类类型的属性名
            column      设置映射关系中的字段名,必须是sql语句查询出来的字段名

        如果使用resultMap,就所有属性都需要设置
-->
    <resultMap id="empResultMap" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
    </resultMap>

    <select id="getAll" resultMap="empResultMap">
        select * from t_emp
    </select>

三、多对一映射

如:查询员工信息以及员工所对应的部门信息

对于在Java实体类层面中维护多对多,一对多的这种映射关系。 需要在“一”的pojo中加入List<多>属性,在“多”的pojo中加入“一”
也就是说,在Dept类中,要加入private List<Emp> emps;在Emp类中,要加入private Dept dept;
在这里插入图片描述
下面我们来看看在mybatis中解决多对一映射关系是如何进行处理,以及处理方法有哪几种 ?

对于多对一关系中,对于SQL的查询,是固定的多表连接查询。这无论是对于哪个需要手写sql的orm框架,这步是少不了的。

 select * from t_emp left join t_dept
            on t_emp.eid = t_dept.did WHERE t_emp.eid = #{eid}

关键是,特定的orm框架如何处理映射关系,下面介绍MyBatis几种常见的处理映射的方法。
对于上文中,已经写了如果是字段有不一致的情况,可以使用resultmap的方式来解决。

0、级联方式处理映射关系

EmpMapper.xml中:

<!--    多对一映射关系,方式一:级联属性赋值-->
    <resultMap id="getEmpAndDeptResultMapOne" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
        <result property="dept.did" column="did"></result>
        <result property="dept.deptName" column="dept_name"></result>
    </resultMap>

<!--        Emp getEmpAndDept(@Param("eid") Integer eid);-->
    <select id="getEmpAndDept" resultMap="getEmpAndDeptResultMapOne">
        select * from t_emp left join t_dept
            on t_emp.eid = t_dept.did WHERE t_emp.eid = #{eid}
    </select>

notice:
IDEA可能会爆红,但是没有关系。
在这里插入图片描述

EmpMapper类中

public interface EmpMapper {
    /**
     * 查询员工及其所对应的部门信息
     */
    Emp getEmpAndDept(@Param("eid") Integer eid);
}

测试类中

    /**
     * 处理多对一的映射关系
     * a> 级联属性赋值
     * b> association
     * c> 分步查询
     */
    @Test
    public void testGetEmpAndDept(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp empAndDept = mapper.getEmpAndDept(1);
        System.out.println(empAndDept);
    }

在这里插入图片描述
最后,确实把dept给查出了。

1、使用association处理映射关系

这种处理映射关系的改变就是把需要处理多对一关系的单独使用association标签来定义了。
EmpMapper.xml

<resultMap id="empDeptMap" type="Emp">
    <id column="eid" property="eid"></id>
    <result column="ename" property="ename"></result>
    <result column="age" property="age"></result>
    <result column="sex" property="sex"></result>
    <association property="dept" javaType="Dept">
        <id column="did" property="did"></id>
        <result column="dname" property="dname"></result>
    </association>
</resultMap>
<!--Emp getEmpAndDeptByEid(@Param("eid") int eid);-->
<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
    select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did =
dept.did where emp.eid = #{eid}
</select>

结果依然和上面一样。

一般我们使用association来进行多对一的关系映射,这种比较形象。

2、分步查询解决多对一关系

对于上述的过程中,我们写的sql都是多表联查的SQL,给数据库发送的是一条查询请求。那我们能不能发送两条,然后将结果拼接?

(1) 查询员工信息

EmpMapper类中

public interface EmpMapper {
	/**
	* 通过分步查询查询员工信息 * @param eid
	* @return
	*/
	Emp getEmpByStep(@Param("eid") int eid);
}

EmpMapper.xml:

<!--    getEmpAndDeptByStepTwo是这条sql语句的全类名-->
    <resultMap id="getEmpAndDeptByStepResultMap" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
        <!--
                select: 设置分步查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
                column:分步查询的条件
                fetchType: 当开启了全局的延迟记载后,可通过此属性手动控制延迟加载的效果
                fetchType:"lazy/eager" lazy表示延迟加载,eager表示立即加载
        -->
        <association property="dept"
                     select="com.fckey.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                     column="did"
                     fetchType="lazy">
        </association>
    </resultMap>

    <select id="getEmpByStep" resultMap="getEmpAndDeptByStepResultMap">
        select * from t_emp where eid = #{eid}
    </select>

(2) 根据员工所对应的部门id查询部门信息

DeptMapper接口:

public interface DeptMapper {
	/**
	* 分步查询的第二步:根据员工所对应的did查询部门信息
	*/
	Dept getEmpDeptByStep(@Param("did") int did);
}

DeptMapper.xml:

<!--        Dept getEmpAndDeptByStepTwo(Integer did);-->
<!--    分步查询可以实现懒加载-->
    <select id="getEmpAndDeptByStepTwo" resultType="Dept">
        select * from t_dept where did = #{did}
    </select>

直接来进行测试一下,发现

@Test
    public void testGetEmpByStep() throws IOException {
        SqlSession sqlSession = getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp empByStep = mapper.getEmpByStep(1);
        System.out.println(empByStep);
    }

在这里插入图片描述

延迟加载

我们知道,对于分步查询,要是每次都发送两条查询语句可能就会造成时间上的损耗,但是,分步查询不是没有优点。
分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息
第一种可以实现粗力度的设置方式,在全局配置文件mybatis-config.xml中:

  • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
  • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个 属性会按需加载
    在这里插入图片描述
    此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过associationcollection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加 载)|eager(立即加载)”.

假设,我现在设计一个场景,查询的就是一个员工的性别,这个没有涉及到对部门的查询。如果部门一起查出来了,说明是立即加载。反之,则是延迟加载。
延迟加载打开:
在这里插入图片描述
立即加载打开:
在这里插入图片描述
通过fetchType参数,可以手动控制延迟加载或立即加载,否则根据全局配置的属性决定是延迟加载还是立即加载。
在这里插入图片描述在这里插入图片描述

三、一对多的关系处理

需求:根据部门id查找部门以及部门中的员工信息

需要查询一对多、多对一的关系,需要在“一”的pojo中加入List<多>属性,在“多”的pojo中加入“一”。
也就是说,在Dept类中,要加入private List<Emp> emps;;在Emp类中,要加入private Dept dept;。然后给他们各自添加get、set方法,重写构造器和toString()

0、使用collection来维系一对多的关系

DeptMapper接口:

public interface DeptMapper {
    /*
    获取部门中所有的员工信息
     */
    Dept getDeptAndEmp(@Param("did") Integer did);
}

DeptMapper.xml

    <resultMap id="deptAndEmpResultMap" type="Dept">
        <id property="did" column="did"></id>
        <result property="deptName" column="dept_name"></result>
<!--
            collection:处理一对多的映射关系
            ofType:表示该属性对应的集合中存储数据的类型
-->
        <collection property="emps" ofType="Emp">
            <id property="eid" column="eid"></id>
            <result property="empName" column="emp_name"></result>
            <result property="age" column="age"></result>
            <result property="sex" column="sex"></result>
            <result property="email" column="email"></result>
        </collection>
    </resultMap>
<!--        Dept getDeptAndEmp(@Param("did") Integer did);-->
    <select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
        select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
    </select>

测试类来进行测试;

  @Test
    public void testGetDeptAndEmp() throws IOException {
        SqlSession sqlSession = getSqlSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        Dept dept = mapper.getDeptAndEmp(1);
        System.out.println(dept.getDeptName());
        dept.getEmps().forEach(System.out::println);
    }

最后结果得出;
在这里插入图片描述

1、分步查询

在处理一对多的关系中,也有分布查询,在分步查询中也有延迟加载立即加载两种。

(1)查询部门信息

DeptMapper接口

public interface DeptMapper {
    /**
     * 分步查询 查询部门及其所有的员工信息
     * 第一步  查询部门信息
     */
    Dept getDeptAndEmoByStepOne(@Param("did") Integer did);
}

DeptMapper.xml

   <!--    分步查询-->
    <resultMap id="deptAndEmoByStepOneMap" type="Dept">
        <id property="did" column="did"></id>
        <result property="deptName" column="dept_name"></result>
        <collection property="emps"
                    select="com.fckey.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
                    column="did"
                    fetchType="lazy"
        >
        </collection>
    </resultMap>
    <!--        Dept getDeptAndEmoByStepOne(@Param("did") Integer did);-->
    <select id="getDeptAndEmoByStepOne" resultMap="deptAndEmoByStepOneMap">
        select * from t_dept where did = #{did}
    </select>

(2)根据部门id查询部门中的所有员工

EmpMapper

public interface EmpMapper {
    /**
     * 分步查询 查询部门及其所有的员工信息
     * 第一步  查询部门信息
     * 第二步  根据查询员工信息
     */
    List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);
}

EmpMapper.xml

<!--    分步查询-->
<!--    List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);-->
    <select id="getDeptAndEmpByStepTwo" resultType="Emp">
        select * from t_emp where did = #{did}
    </select>

(3)测试类

  @Test
    public void testGetDeptAndEmp() throws IOException {
        SqlSession sqlSession = getSqlSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        Dept dept = mapper.getDeptAndEmp(1);
        System.out.println(dept.getDeptName());
        System.out.println("====================");
        dept.getEmps().forEach(System.out::println);
    }

然后,设置的是延迟加载的模式,运行结果如下所示
在这里插入图片描述


然后,有人问,有一对多,多对一,那多对多的关系呢?对于多对多的关系需要抽离出第三张表,本质上还是一对多,多对一的变体。

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

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

相关文章

6.1 SpringBoot解决跨域,我推荐这2种超实用方案

文章目录 前言一、验证跨域1. 添加index.html2. 增加/auth/test/cors接口3. IDEA启动多个springboot项目4. 验证POST方法5. 验证OPTIONS方法 二、拦截器方案定义拦截器注册拦截器&#xff0c;并指定拦截规则 三、过滤器方案总结最后 前言 在文章【2-2】中&#xff0c;我和你介…

获取企业服务超市企业信息

地址&#xff1a; 服务机构-苏州工业园区企业服务超市 import os from datetime import datetime from urllib import request import pandas as pd import re import requests from lxml import etree from bs4 import BeautifulSoup import csv import codecs# 20230521 根据…

learn_C_deep_13 (深刻理解宏定义)

目录 宏定义 数值宏常量 字符串宏常量 用定义充当注释符号宏 用 define 宏定义表达式 宏定义中的空格 宏定义 数值宏常量 在C语言中&#xff0c;宏定义可以用于定义数值宏常量。数值宏常量是一个值&#xff0c;在宏定义中用一个常量名称来表示&#xff0c;该值在后续的代…

计算机视觉的应用5-利用PCA降维方法实现简易人脸识别模型

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用5-利用PCA降维方法实现简易人脸识别模型&#xff0c;本文将介绍如何使用主成分分析&#xff08;PCA&#xff09;实现简易的人脸识别模型。首先&#xff0c;我们将简要介绍PCA的原理及其在人脸识别中…

26 KVM热迁移虚拟机

文章目录 26 KVM热迁移虚拟机26.1 总体介绍26.1.1 概述26.1.2 应用场景26.1.3 注意事项和约束限制 26.2 热迁移操作26.2.1 前提条件26.2.2 热迁移脏页率预测&#xff08;可选&#xff09;26.2.3 设置热迁移参数&#xff08;可选&#xff09;26.2.4 热迁移操作&#xff08;共享存…

Linux:文本三剑客之awk

Linux&#xff1a;文本三剑客之awk 一、awk编辑器1.1 awk概述1.2 awk工作原理1.3 awk与sed的区别 二、awk的应用2.1 命令格式2.2 awk常见的内建变量&#xff08;可直接用&#xff09; 三、awk使用3.1 按行输出文本3.2 按字段输出文本3.3 通过管道、双引号调用 Shell 命令 一、a…

【模电实验】日光灯电路及功率因数的提高

实验4 日光灯电路及功率因数的提高 一、实验目的 1&#xff0e;理解提高功率因数的意义并掌握其方法。 2&#xff0e;掌握日光灯电路的联接。 二、原理说明 日光灯电路结构及工作原理 日光灯电路如图4-1所示&#xff0c;日光灯由灯管、镇流器和启辉器三部分组成。 &…

复制带随机指针的链表

&#x1f495;“如果你关注自己已经拥有的&#xff0c;你就会拥有更多。如果你只关注自己没有得到的&#xff0c;你永远不会满足。” - 奥普拉温弗瑞&#x1f495; &#x1f43c;作者&#xff1a;不能再留遗憾了&#x1f43c; &#x1f386;专栏&#xff1a;Java学习&#x1f3…

11. Redis集群(cluster)

11. Redis集群cluster 是什么&#xff1f;能干嘛&#xff1f;集群算法-分片-槽位slot官网出处redis集群的槽位slotredis集群的分片他两的优势slot槽位映射&#xff0c;一般业界有3种解决方案哈希取余分区—致性哈希算法分区3大步骤算法构建一致性哈希环redis服务器IP节点映射k…

【Python sqlite3】零基础也能轻松掌握的学习路线与参考资料

Python sqlite3是Python语言自带的轻量级关系数据库管理系统&#xff0c;它可以让我们在不需要额外的安装和配置下&#xff0c;使用SQLite数据库进行操作和管理。SQLite是一个功能强大的嵌入式数据库&#xff0c;它非常适合在轻量级应用程序中使用&#xff0c;如桌面应用程序、…

ROS学习(4)——launch文件的编写

对于一个复杂的系统,会有十几个、几十个甚至是上百个节点在运行,如果我们每次都是采取“打 开终端、运行 rosrun 指令”来启动应用程序,显得效率非常低。我们需要一个更方便的方式来启动系统。ROS 中提供了“使用 launch 文件 roslaunch”命令来完成系统的启动。具体的实现方法…

Java·Lambda

文章目录 ⚽️1 背景⚽️&#x1f34f;1.1 Lambda表达式的语法&#x1f34f;&#x1f34e;1.2 函数式接口&#x1f34e; &#x1f3c0;2 Lambda表达式的基本使用&#x1f3c0;&#x1f348;2.1 语法精简&#x1f348; &#x1f3c8;3 变量捕获&#x1f3c8;&#x1f3c6;3.1 匿…

Linux Audio (7) DAPM-4 Path/Route添加过程

DAPM-4 Path/Route添加过程 route分类&#xff1a;route转化为Pathcodec驱动add widgetMechine驱动add kcontrol route分类&#xff1a; 常规route {“sink”, NULL, “source”}&#xff0c;其path->connect1 sink widget是Mixer {“Mixer”, name1, “source1”} {“Mixe…

chatgpt赋能Python-python88

Python88 简介 Python88 是一个优秀的 Python 开源库&#xff0c;它提供了许多有用的函数和工具&#xff0c;可用于创建高效的 Web 应用程序&#xff0c;简化数据分析、数据可视化以及机器学习和人工智能任务等。 Python88 帮助开发人员以更简单、更快捷的方式编写代码&#…

VS Code Remote Development

1、Ubuntu 上启用 SSH &#xff08;1&#xff09;打开终端&#xff0c;并且安装openssh-server软件包&#xff1a; sudo apt update sudo apt install openssh-server 当被提示时&#xff0c;输入你的密码并且按 Enter&#xff0c;继续安装。 &#xff08;2&#xff09;安…

RocketMQ消息发送

消息发送示例代码&#xff1a; public static void main(String[] args) throws MQClientException, InterruptedException {DefaultMQProducer producer new DefaultMQProducer("please_rename_unique_group_name");producer.setNamesrvAddr("127.0.0.1:9876…

leetcode-743. 网络延迟时间

1.思路分析&#xff1a; 一道Dijkstra模板题 推荐Dijkstra算法讲解教程 Dijkstra&#xff08;有向图某点到其他所有点的最短路径问题&#xff09; Dijkstra算法的基本思想是贪心策略&#xff0c;每次从未确定最短路径的顶点中选择距离源点最近的一个&#xff0c;然后以该顶点…

Python使用正则表达式

正则表达式&#xff08;Regular Expression&#xff09;&#xff0c;又称规则表达式&#xff0c;是一个计算机科学的概念&#xff0c;通常被用来检索和替换符合某些规则的文本。 1. 正则表达式语法 正则表达式就是记录文本规则的代码。 1. 行定位符 行定位符就是用来描述字…

【STM32G431RBTx】备战蓝桥杯嵌入式→决赛试题→第十二届

文章目录 前言一、题目二、模块初始化三、代码实现interrupt.h:interrupt.c:main.h:main.c: 四、完成效果五、总结 前言 无 一、题目 二、模块初始化 1.LCD这里不用配置&#xff0c;直接使用提供的资源包就行 2.ADC:开启ADCsingle-ended 3.LED:开启PC8-15,PD2输出模式就行了…

MySQL高级(InnoDB引擎)

&#xff08;一&#xff09;逻辑存储结构 表空间&#xff08;ibd文件&#xff09;&#xff0c;会生成ibd文件&#xff0c;一个mysql实例可以对应多个表空间&#xff0c;用于存储记录、索引等数据。 段&#xff0c;分为数据段&#xff08;Leaf node segment&#xff09;、索引段…