SSM - Springboot - MyBatis-Plus 全栈体系(十四)

news2024/11/17 20:40:18

第三章 MyBatis

二、MyBatis 基本使用

1. 向 SQL 语句传参

1.1 mybatis 日志输出配置
  • mybatis配置文件设计标签和顶层结构如下:

  • configuration(配置)

    • properties(属性)
    • settings(设置)
    • typeAliases(类型别名)
    • typeHandlers(类型处理器)
    • objectFactory(对象工厂)
    • plugins(插件)
    • environments(环境配置)
      • environment(环境变量)
        • transactionManager(事务管理器)
        • dataSource(数据源)
    • databaseIdProvider(数据库厂商标识)
    • mappers(映射器)
  • 我们可以在mybatis的配置文件使用settings标签设置,输出运过程SQL日志!

  • 通过查看日志,我们可以判定#{} 和 ${}的输出效果!

  • settings设置项:

    • logImpl
    • 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
    • SLF4J | LOG4J(3.5.9 起废弃) | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING
    • 未设置
  • 日志配置:

<settings>
  <!-- SLF4J 选择slf4j输出! -->
  <setting name="logImpl" value="SLF4J"/>
</settings>
1.2 #{} 形式
  • Mybatis会将SQL语句中的#{}转换为问号占位符。

在这里插入图片描述

1.3 ${} 形式

在这里插入图片描述

  • 通常不会采用${}的方式传值。一个特定的适用场景是:通过Java程序动态生成数据库表,表名部分需要Java程序通过参数传入;而JDBC对于表名部分是不能使用问号占位符的,此时只能使用
  • 结论:实际开发中,能用#{}实现的,肯定不用${}。
  • 特殊情况: 动态的不是值,是列名或者关键字,需要使用${}拼接
//注解方式传入参数!!
@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, 
                                @Param("value") String value);

2. 数据输入

2.1 Mybatis 总体机制概括

在这里插入图片描述

2.2 概念说明
  • 这里数据输入具体是指上层方法(例如Service方法)调用Mapper接口时,数据传入的形式。

  • 简单类型:只包含一个值的数据类型

    • 基本数据类型:int、byte、short、double、……
    • 基本数据类型的包装类型:Integer、Character、Double、……
    • 字符串类型:String
  • 复杂类型:包含多个值的数据类型

    • 实体类类型:Employee、Department、……
    • 集合类型:List、Set、Map、……
    • 数组类型:int[]、String[]、……
    • 复合类型:List、实体类中包含集合……
2.3 单个简单类型参数
  • Mapper接口中抽象方法的声明
Employee selectEmployee(Integer empId);
  • SQL语句
<select id="selectEmployee" resultType="com.alex.mybatis.entity.Employee">
  select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId}
</select>

单个简单类型参数,在#{}中可以随意命名,但是没有必要。通常还是使用和接口方法参数同名。

2.4 实体类类型参数
  • Mapper接口中抽象方法的声明
int insertEmployee(Employee employee);
  • SQL语句
<insert id="insertEmployee">
  insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
</insert>
  • 对应关系
    在这里插入图片描述
  • 结论
    • Mybatis会根据#{}中传入的数据,加工成getXxx()方法,通过反射在实体类对象中调用这个方法,从而获取到对应的数据。填充到#{}解析后的问号占位符这个位置。
2.5 零散的简单类型数据

在这里插入图片描述

  • Mapper接口中抽象方法的声明
int updateEmployee(@Param("empId") Integer empId,@Param("empSalary") Double empSalary);
  • SQL语句
<update id="updateEmployee">
  update t_emp set emp_salary=#{empSalary} where emp_id=#{empId}
</update>
  • 对应关系
    在这里插入图片描述
2.6 Map 类型参数
  • Mapper接口中抽象方法的声明
int updateEmployeeByMap(Map<String, Object> paramMap);
  • SQL语句
<update id="updateEmployeeByMap">

  update t_emp set emp_salary=#{empSalaryKey} where emp_id=#{empIdKey}

</update>
  • junit测试
private SqlSession session;
//junit5会在每一个@Test方法前执行@BeforeEach方法
@BeforeEach
public void init() throws IOException {
    session = new SqlSessionFactoryBuilder()
            .build(
                    Resources.getResourceAsStream("mybatis-config.xml"))
            .openSession();
}

@Test
public void testUpdateEmpNameByMap() {
  EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
  Map<String, Object> paramMap = new HashMap<>();
  paramMap.put("empSalaryKey", 999.99);
  paramMap.put("empIdKey", 5);
  int result = mapper.updateEmployeeByMap(paramMap);
  log.info("result = " + result);
}

//junit5会在每一个@Test方法后执行@@AfterEach方法
@AfterEach
public void clear() {
    session.commit();
    session.close();
}

  • 对应关系

    • #{}中写Map中的key
  • 使用场景

    • 有很多零散的参数需要传递,但是没有对应的实体类类型可以使用。使用@Param注解一个一个传入又太麻烦了。所以都封装到Map中。

3. 数据输出

3.1 输出概述
  • 数据输出总体上有两种形式:

    • 增删改操作返回的受影响行数:直接使用 int 或 long 类型接收即可
    • 查询操作的查询结果
  • 我们需要做的是,指定查询的输出数据类型即可!

  • 并且插入场景下,实现主键数据回显示!

3.2 单个简单类型
  • Mapper接口中的抽象方法
int selectEmpCount();
  • SQL语句
<select id="selectEmpCount" resultType="int">
  select count(*) from t_emp
</select>

Mybatis 内部给常用的数据类型设定了很多别名。 以 int 类型为例,可以写的名称有:int、integer、Integer、java.lang.Integer、Int、INT、INTEGER 等等。

  • junit测试
@Test
public void testEmpCount() {

  EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);

  int count = employeeMapper.selectEmpCount();

  log.info("count = " + count);

}
  • 细节解释:

    • select标签,通过resultType指定查询返回值类型!

    • resultType = “全限定符 | 别名 | 如果是返回集合类型,写范型类型即可”

  • 别名问题:

    • 类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
    <typeAliases>
      <typeAlias alias="Author" type="domain.blog.Author"/>
      <typeAlias alias="Blog" type="domain.blog.Blog"/>
    </typeAliases>
    
    • 当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。

    • 也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:

    <typeAliases> <package name="domain.blog"/> </typeAliases>
    
    • 每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。见下面的例子:
    @Alias("author")
    public class Author {
        ...
    }
    
  • 下面是Mybatis为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

别名映射的类型
_bytebyte
_char (since 3.5.10)char
_character (since 3.5.10)char
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
char (since 3.5.10)Character
character (since 3.5.10)Character
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
bigintegerBigInteger
objectObject
object[]Object[]
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
3.3 返回实体类对象
  • Mapper接口的抽象方法
Employee selectEmployee(Integer empId);
  • SQL语句
<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.alex.mybatis.entity.Employee">

  <!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 -->
  <!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
  select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}

</select>
  • 通过给数据库表字段加别名,让查询结果的每一列都和Java实体类中属性对应起来。

  • 增加全局配置自动识别对应关系

  • 在 Mybatis 全局配置文件中,做了下面的配置,select语句中可以不给字段设置别名

<!-- 在全局范围内对Mybatis进行配置 -->
<settings>

  <!-- 具体配置 -->
  <!-- 从org.apache.ibatis.session.Configuration类中可以查看能使用的配置项 -->
  <!-- 将mapUnderscoreToCamelCase属性配置为true,表示开启自动映射驼峰式命名规则 -->
  <!-- 规则要求数据库表字段命名方式:单词_单词 -->
  <!-- 规则要求Java实体类属性名命名方式:首字母小写的驼峰式命名 -->
  <setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>
3.4 返回 Map 类型
  • 适用于SQL查询返回的各个字段综合起来并不和任何一个现有的实体类对应,没法封装到实体类对象中。能够封装成实体类类型的,就不使用Map类型。

  • Mapper接口的抽象方法

Map<String,Object> selectEmpNameAndMaxSalary();
  • SQL语句
<!-- Map<String,Object> selectEmpNameAndMaxSalary(); -->
<!-- 返回工资最高的员工的姓名和他的工资 -->
<select id="selectEmpNameAndMaxSalary" resultType="map">
  SELECT
    emp_name 员工姓名,
    emp_salary 员工工资,
    (SELECT AVG(emp_salary) FROM t_emp) 部门平均工资
  FROM t_emp WHERE emp_salary=(
    SELECT MAX(emp_salary) FROM t_emp
  )
</select>
  • junit测试
@Test
public void testQueryEmpNameAndSalary() {

  EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);

  Map<String, Object> resultMap = employeeMapper.selectEmpNameAndMaxSalary();

  Set<Map.Entry<String, Object>> entrySet = resultMap.entrySet();

  for (Map.Entry<String, Object> entry : entrySet) {

    String key = entry.getKey();

    Object value = entry.getValue();

    log.info(key + "=" + value);

  }
}
3.5 返回 List 类型
  • 查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回。此时不需要任何特殊处理,在resultType属性中还是设置实体类类型即可。

  • Mapper接口中抽象方法

List<Employee> selectAll();
  • SQL语句
<!-- List<Employee> selectAll(); -->
<select id="selectAll" resultType="com.alex.mybatis.entity.Employee">
  select emp_id empId,emp_name empName,emp_salary empSalary
  from t_emp
</select>
  • junit测试
@Test
public void testSelectAll() {
  EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
  List<Employee> employeeList = employeeMapper.selectAll();
  for (Employee employee : employeeList) {
    log.info("employee = " + employee);
  }
}
3.6 返回主键值
3.6.1 自增长类型主键
  • Mapper接口中的抽象方法
int insertEmployee(Employee employee);
  • SQL语句
<!-- int insertEmployee(Employee employee); -->
<!-- useGeneratedKeys属性字面意思就是“使用生成的主键” -->
<!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="empId">
  insert into t_emp(emp_name,emp_salary)
  values(#{empName},#{empSalary})
</insert>
  • junit测试
@Test
public void testSaveEmp() {
  EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
  Employee employee = new Employee();
  employee.setEmpName("john");
  employee.setEmpSalary(666.66);
  employeeMapper.insertEmployee(employee);
  log.info("employee.getEmpId() = " + employee.getEmpId());
}
  • 注意

    • Mybatis是将自增主键的值设置到实体类对象中,而不是以Mapper接口方法返回值的形式返回。
3.6.2 非自增长类型主键
  • 而对于不支持自增型主键的数据库(例如 Oracle)或者字符串类型主键,则可以使用 selectKey 子元素:selectKey 元素将会首先运行,id 会被设置,然后插入语句会被调用!
  • 使用 selectKey 帮助插入UUID作为字符串类型主键示例:
<insert id="insertUser" parameterType="User">
    <selectKey keyProperty="id" resultType="java.lang.String"
        order="BEFORE">
        SELECT UUID() as id
    </selectKey>
    INSERT INTO user (id, username, password) 
    VALUES (
        #{id},
        #{username},
        #{password}
    )
</insert>
  • 在上例中,我们定义了一个 insertUser 的插入语句来将 User 对象插入到 user 表中。我们使用 selectKey 来查询 UUID 并设置到 id 字段中。
  • 通过 keyProperty 属性来指定查询到的 UUID 赋值给对象中的 id 属性,而 resultType 属性指定了 UUID 的类型为 java.lang.String
  • 需要注意的是,我们将 selectKey 放在了插入语句的前面,这是因为 MySQL 在 insert 语句中只支持一个 select 子句,而 selectKey 中查询 UUID 的语句就是一个 select 子句,因此我们需要将其放在前面。
  • 最后,在将 User 对象插入到 user 表中时,我们直接使用对象中的 id 属性来插入主键值。
  • 使用这种方式,我们可以方便地插入 UUID 作为字符串类型主键。当然,还有其他插入方式可以使用,如使用Java代码生成UUID并在类中显式设置值等。需要根据具体应用场景和需求选择合适的插入方式。
3.7 实体类属性和数据库字段对应关系
3.7.1 别名对应
  • 将字段的别名设置成和实体类属性一致。
<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.alex.mybatis.entity.Employee">

  <!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 -->
  <!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
  select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}

</select>

关于实体类属性的约定:
getXxx()方法、setXxx()方法把方法名中的get或set去掉,首字母小写。

3.7.2 全局配置自动识别驼峰式命名规则
  • 在Mybatis全局配置文件加入如下配置:
<!-- 使用settings对Mybatis全局进行设置 -->
<settings>

  <!-- 将xxx_xxx这样的列名自动映射到xxXxx这样驼峰式命名的属性名 -->
  <setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>
  • SQL语句中可以不使用别名
<!-- Employee selectEmployee(Integer empId); -->
<select id="selectEmployee" resultType="com.alex.mybatis.entity.Employee">

  select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}

</select>
3.7.3 使用resultMap
  • 使用resultMap标签定义对应关系,再在后面的SQL语句中引用这个对应关系
<!-- 专门声明一个resultMap设定column到property之间的对应关系 -->
<resultMap id="selectEmployeeByRMResultMap" type="com.alex.mybatis.entity.Employee">

  <!-- 使用id标签设置主键列和主键属性之间的对应关系 -->
  <!-- column属性用于指定字段名;property属性用于指定Java实体类属性名 -->
  <id column="emp_id" property="empId"/>

  <!-- 使用result标签设置普通字段和Java实体类属性之间的关系 -->
  <result column="emp_name" property="empName"/>

  <result column="emp_salary" property="empSalary"/>

</resultMap>

<!-- Employee selectEmployeeByRM(Integer empId); -->
<select id="selectEmployeeByRM" resultMap="selectEmployeeByRMResultMap">

  select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}

</select>

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

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

相关文章

7、SpringBoot_高级配置

一、配置高级 1.临时属性设置 1.1引出问题 如果目标电脑上8080端口已经使用&#xff0c;再次使用该端口会出现端口占用问题 解决方式 重新更换配置文件修改端口打包通过临时属性配置新端口更换配置文件 1.2添加临时属性配置 通过临时属性修改8080端口 java -jar 项目.jar…

zemax目镜调焦演示

目镜的焦距应当是可变的&#xff0c;就像我们使用显微镜时&#xff0c;可以通过旋转调节旋钮&#xff0c;使得图像变得清晰&#xff0c;目镜的焦距也可以调整&#xff0c;使得要被观察的像出现在合适的位置。 这样&#xff0c;不同的人都可以使用同一台仪器&#xff0c;不管近…

Spring5应用之AOP额外功能详解

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Spring5应用专栏_Aomsir的博客-CSDN博客 文章目录 前言MethodBefore…

Doris数据库FE——启动流程源码详细解析

Doris中FE主要负责接收和返回客户端请求、元数据以及集群管理、查询计划生成等工作。代码路径&#xff1a;doris/fe/fe-core/src/main/java/org/apache/doris/DorisFE.java 环境检查 在启动FE的时候&#xff0c;主要做环境检查。检查一些启动时必要的环境变量以及初始化配置…

社区团购新零售搭伙拼团小程序源码(前后端)

社区团购新零售搭伙拼团小程序源码是一款非常实用的电商小程序&#xff0c;它包含了前后端文件&#xff0c; 可以快速地进行部署和使用。该小程序是基于微信小程序开发的&#xff0c;支持社区团购、新零售、搭伙拼团等多种功能。 该小程序具有良好的用户体验&#xff0c;包括…

范数Norm-衡量向量大小的方法

性质 非负性: 范数的值总是非负的,且当且仅当向量全为零时,范数的值为零。 齐次性: 对于任意实数α,有 三角不等式: 对于任意向量x和y,有 常见范数 L1: 向量所有元素绝对值的和,权重稀疏 L2:欧几里得范数,权重平滑 无穷范数:表示向量中最大的元素 为什么使用范…

英飞凌 Tricore 架构中断系统详解

本文以TC3系列MCU为例&#xff0c;先来了解中断源是如何产生的&#xff0c;再看一下CPU是如何处理中断源的。 AURIX TC3XX的中断路由模块 Interrupt Router (IR) 在TC3中&#xff0c;中断既可以被CPU处理&#xff0c;也可以被DMA处理&#xff0c;所以手册中不再把中断称为中断…

vue3硅谷甄选02 | 封装svg组件 - axios二次封装

文章目录 vue3硅谷甄选02功能1&#xff1a;封装svg组件SVG图标配置svg封装成组件svg组件注册为全局组件自定义统一注册全局组件的插件自定义插件的原理插件的使用 app.use(plugin, [options]) 功能2&#xff1a;axios二次封装使用mock插件构造数据axios二次封装api接口统一管理…

【大数据开发技术】实验01-Hadoop安装部署

文章目录 Hadoop安装部署一、实验目标二、实验要求三、实验内容四、实验步骤附&#xff1a;系列文章 Hadoop安装部署 虚拟机数量&#xff1a;3 系统版本&#xff1a;Centos 7.5 Hadoop版本&#xff1a; Apache Hadoop 2.7.3 主节点信息&#xff1a; 操作系统&#xff1a;Cen…

Tomcat 与 JDK 对应版本关系

对应关系 Tomcat版本 jdk版本11.0.x JDK 21及以后10.1.x JDK11及以后10.0.xJDK1.8及以后9.0.x JDK1.8及以后8.5.xJDK1.7及以后8.0.x JDK1.7及以后 查看对应关系方法&#xff1a; 登陆Tomcat官网&#xff1a;Apache Tomcat - Welcome! 结果&#xff1a;

Arthas:Java调试利器使用

Arthas:Java调试利器使用 1. Arthas是什么2. Arthas可以解决什么问题Arthas启动方式1. jar启动2. 在线安装 远程连接命令使用- 退出threadclassloaderscsm watchtrace修改日志级别 1. Arthas是什么 Arthas(阿尔萨斯)是阿里开源的一个Java在线分析诊断工具. 2. Arthas可以解决…

C#(CSharp)入门实践项目(简易回合制游戏)

项目名称 木木夕营救公主 项目介绍 这是一个小游戏&#xff0c;你将扮演一个英雄&#xff08;木木夕&#xff09;&#xff0c;去打败恶龙&#xff0c;拯救出公主&#xff0c;该项目采用回合制战斗模式&#xff0c;由于角色的血量和攻击为随机数&#xff0c;所以需要靠运气才…

YOLOv7改进:CBAM注意力机制

目录 1.介绍 1.1、论文的出发点 1.2、论文的主要工作 1.3、CBAM模块的具体介绍 2.YOLOv7改进 2.1yaml 配置文件如下 2.2common.py配置 2.3yolo.py配置 1.介绍 1.1、论文的出发点 cnn基于其丰富的表征能力&#xff0c;极大地推动了视觉任务的完成&#xff0c;为了提高…

【MySql】3- 实践篇(一)

文章目录 1. 普通索引和唯一索引的选择1.1 查询过程1.2 更新过程1.2.1 change buffer1.2.2 change buffer 的使用场景 1.3 索引选择和实践1.4 change buffer 和 redo log2. MySQL为何有时会选错索引?2.1 优化器的逻辑2.1.1 扫描行数是怎么判断的?2.1.2 重新统计索引信息 2.2 …

一站式吃鸡利器,提升游戏战斗力,助您稳坐鸡王宝座!

各位吃鸡玩家们&#xff0c;听说过绝地求生作图工具吗&#xff1f;想知道如何提高游戏战斗力、分享顶级作战干货、查询装备皮肤库存&#xff1f;还在为游戏账号安全而担心吗&#xff1f;别急&#xff0c;今天就为您介绍一款一站式吃鸡利器&#xff0c;满足您的所有需求&#xf…

【使用工具】IDEA创建类及已有类添加注释-详细操作

1.背景 很多开发好多时候其实不太会给类添加注释&#xff0c;尤其是已经有的类&#xff0c;上网查询&#xff0c;好多文档错误百出&#xff0c;而且不全 2.正文 2.1新建类添加注释 idea给新建类创建注释有两种方式 先写一个简单的模板 /** * description: TODO * autho…

kotlin协程CoroutineScope Dispatchers.IO launch 线程Id

kotlin协程CoroutineScope Dispatchers.IO launch 线程Id import kotlinx.coroutines.*fun main(args: Array<String>) {println("main 线程id:${Thread.currentThread().threadId()}")CoroutineScope(Dispatchers.IO).launch {println("launch 线程id:$…

【JVM】第二篇 JVM内存模型深度剖析与优化

目录 一. JDK体系结构与跨平台特性介绍二. JVM内存模型深度剖析三. 从Jvisualvm来研究下对象内存流转模型四. GC Root与STW机制五. JVM参数设置通用模型一. JDK体系结构与跨平台特性介绍 二. JVM内存模型深度剖析 按照线程是否共享来划分 TLAB(Thread Local Allocation Buffer…

mybatis核心组件

title: “mybatis核心组件” createTime: 2021-12-08T12:19:5708:00 updateTime: 2021-12-08T12:19:5708:00 draft: false author: “ggball” tags: [“mybatis”] categories: [“java”] description: “mybatis核心组件” #mermaid-svg-AYu4pQutsPsK0P5T {font-family:&quo…

stm32 - 初识2

stm32 - 初识2 工程架构点灯程序寄存器方式点灯库函数的方式点灯 工程架构 启动文件 中断向量表&#xff0c;中断服务函数&#xff0c;其他中断等 中断服务函数中的&#xff0c;复位中断是整个程序的入口&#xff0c;调用systeminit&#xff0c;和main函数 点灯程序 寄存器方式…