Mybatis基础教程及使用细节
本篇主要对Mybatis基础使用进行总结,包括Mybatis的基础操作,使用注解进行增删改查的练习;详细介绍xml映射文件配置过程并且使用xml映射文件进行动态sql语句进行条件查询;为了简化java开发提高效率,介绍一下依赖,例如lombok依赖等。后续会对Mybatisplus进行总结。
目录
一、什么是Mybatis:
二、小细节:
三、Mybatis基础操作:
使用注解实现增删改查操作:
删除操作:
插入操作:
更新操作:
查询操作:
四、xml映射文件的使用
如何配置xml映射文件:
第一条规范:
第二条规范:
五、动态sql语句
动态查询操作:
动态更新操作:
批量删除操作:
一、什么是Mybatis:
- Mybatis是持久层框架,也就是前面篇章讲的DAO层框架,用于简化JDBC的开发,前面介绍过jdbc,使用起来比较复杂:需要导入依赖然后创建连接,编写sql语句,创建载具(传输sql)然后对结果进行解析等操作,引入Mybatis极大简化了对数据的操作。
- MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 映射成数据库中的记录。
二、小细节:
数据库连接池更换:
springboot中自带的数据库连接池是HikariDataSource,如果想更换的话,例如Druid,只需要将这个依赖的坐标配置到pom.xml文件中即可;
lombok依赖:
当我们获取数据库数据的时候,需要用一个实体类与数据库的数据去对应,然后将数据封装在实体类对象中,但是自己去实现这个类的时候发现代码量也比较多,get、set方法以及无参数的构造器和有参数的构造器等等需要自己去生成,整体上比较臃肿,所以可以音符一个依赖,然后使用相应注解去简化这个操作:
lombok是一个实用的java类库,能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并且可以自动化生成日志变量,简化开发,提高效率。注解如下:
在pom.xml文件中引入如下依赖:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
更改后:下面各种方法就不用自己手动实现了。
package com.springboot_mybatis.pojo;import lombok.*;//pojo这个包专门用来放实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Integer id;private String name;private Short age;private Short gender;private String phone;
// public User() {
// }
//
// public User(Integer id, String name, Short age, Short gender, String phone) {
// this.id = id;
// this.name = name;
// this.age = age;
// this.gender = gender;
// this.phone = phone;
// }// public Integer getId() {
// return id;
// }
//
// public String getName() {
// return name;
// }
//
// public Short getAge() {
// return age;
// }
//
// public Short getGender() {
// return gender;
// }
//
// public String getPhone() {
// return phone;
// }
//
// @Override
// public String toString() {
// return "User{" +
// "id=" + id +
// ", name='" + name + '\'' +
// ", age=" + age +
// ", gender=" + gender +
// ", phone='" + phone + '\'' +
// '}';
// }
//
// public void setId(Integer id) {
// this.id = id;
// }
//
// public void setName(String name) {
// this.name = name;
// }
//
// public void setAge(Short age) {
// this.age = age;
// }
//
// public void setGender(Short gender) {
// this.gender = gender;
// }
//
// public void setPhone(String phone) {
// this.phone = phone;
// }
}
三、Mybatis基础操作:
使用注解实现增删改查操作:
准备工作:
- 准备数据库表:emp。
- 创建一个新的springboot工程,然后引入起步依赖:mybatis、mysql驱动、lombok依赖等。
- application.properties中配置数据库连接信息,包括user,password,数据库名称等。
- 创建实体类Emp用来封装数据库数据。
- 准备Mapper接口EmpMapper对数据库进行操作,要知道Mapper中是写sql语句的,需要给里面传递参数,来进行数据库操作;
- 创建好数据库表后,连接数据库:点击右侧Database
然后点击+号:
- 选择Mysql:
- 填上对应的信息,user、password、数据库表名称等即可完成。
工程整体结构如下:
删除操作:
EmpMapper代码:方法前要添加Delete注解,表示删除操作,然后里面写具体的sql代码。
@Mapper
public interface EmpMapper {//TODO 根据ID删除数据操作:此处删除的话需要指定id,所以此处需要传入一个id;@Delete("delete from emp where id=#{id}")
// public void delete(Integer id);public int delete(Integer id);
在test文件中进行测试: 此处进行依赖注入EmpMapper类的对象,然后调用delete方法并传入参数,即可对该数据库进行操作。
//在定义好了接口以及数据库的数据以及对应的User类后,需要进行测试,测试需要在test文件中进行;
@SpringBootTest//这个就是springboot整合单元测试的注解
class SpringbootMybatisCrudApplicationTests {//注意在UserMapper接口中注解了Mapper,所以在容器中已经有了实现这个接口的对象,所以只需要依赖注入即可使用;@Autowiredprivate EmpMapper empMapper;@Testpublic void testDelete(){int delete = empMapper.delete(17);//此处别忘了传递参数;System.out.println("删除的行数:"+delete);}
在进行例如删除操作后,并不知道执行的过程,可以在配置文件中进行配置:在application.properties文件中配置日志输出,配置好后,可以在控制台中输出日志信息:
#配置mybatis的日志,指定输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
配置好后完成删除操作后会控制台会显示如下信息:
插入操作:
主键回显:
为什么要获取主键:在一个表中添加数据之后,一般还需要维护其关系表数据,所以要获取到主键,然后再对其关系表数据进行操作。
在数据插入成功后,需要获取插入数据库数据的主键,例如,id为主键,刚插入的id为12,想获取12这个值,一般主键是自增的,所以不用手动写(下方代码也没有传入id这个值),所以想获取主键可以用这个注解的方法来实现;
获取方法:
在insert注解前面再添加一个注解:@Options(keyProperty=”id”,userGeneratedKeys=true),这样就会自动将生成的主键值赋值给emp对象的id属性,否则不会给id属性赋值;
EmpMapper中代码:会直接从对象中的属性取值:
//TODO 新增员工:注意如果在values里面添加值的话,这样就写死了,复用性差,所以想直接传递一个对象;注意这里的#{}里面的参数是属性,要和属性名一样@Options(useGeneratedKeys = true,keyProperty = "id")//主键回显,自动将主键值赋值给该对象的id属性;这样就可以拿到主键值了;@Insert("insert into emp(username,name,gender,image,job,entrydate,dept_id,create_time,update_time) values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")public void insert(Emp emp);
test文件中测试:将对象属性赋值,然后调用insert方法
@Testpublic void testInsert(){Emp emp=new Emp();emp.setUsername("Tom1");emp.setName("汤姆1");emp.setImage("1.jpg");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(2000,1,1));emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);empMapper.insert(emp);//测试是否能拿到主键值:System.out.println(emp.getId());}
更新操作:
EmpMapper中代码:
@Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image},job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")public void update(Emp emp);
test测试:注意此处有点缺陷,是新创建了一个Emp对象,并且调用update方法并传入这个对象作为参数,所以更新的话需要全部属性都要更新,如果少对emp对象属性赋值的话,那么数据库中的相应属性也会为null。后续会采用动态sql。
@Test//测试更新方法public void testUpdate(){Emp emp=new Emp();emp.setId(22);emp.setUsername("Jerry");emp.setName("杰瑞");emp.setImage("1.jpg");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(2000,1,1));emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);empMapper.update(emp);}
查询操作:
查询操作有一点坑:
如果采用第一种方法,在数据库中属性名为dept_id,而实体类对象中的属性名为deptId,二者名称不同,会导致mybatis从数据库查询到的数据不会自动封装到对应属性当中;采用第三种方法,在properties文件中进行配置,如下代码即可自动将dept_id封装到驼峰命名deptId:
#开启mybatis的驼峰命名自动映射开关---可以将数据库中属性a_dan自动封装到实体类的属性aDan;
mybatis.configuration.map-underscore-to-camel-case=true
EmpMapper中代码:
//TODO 查询指定数据:(查询所有数据在前面项目中已经展示,返回类型为对象集合)//下面这个方法是不合理的,因为如果数据库中的属性名和实体类的属性名不相同的话mybatis不会自动封装也就是这几个值不会自动给类的属性赋值,所以这几个属性的值为null;
// @Select("select *from emp where id=#{id}")
// public Emp select(Integer id);//通过@Result注解,手动进行映射封装:(不推荐这种方法,比较复杂)
// @Results({
// //一个@Result代表将一列映射到一个属性;有三个属性和数据库列不一致,所以要写三个:
// @Result(column = "dept_id",property = "deptId"),
// @Result(column = "create_time",property = "createTime"),
// @Result(column = "update_time",property = "updateTime")
// })
// @Select("select*from emp where id=#{id}")
// public Emp select(Integer id);
//!!!推荐的方法:开启mybatis的驼峰命名自动映射开关---可以将数据库中属性a_dan自动封装到实体类的属性aDan;
// 需要在resources资源文件中的配置文件中进行配置:配置好后,原来的代码怎么写现在就怎么写:@Select("select *from emp where id=#{id}")public Emp select(Integer id);
test测试:
public void testSelect(){Emp emp = empMapper.select(1);System.out.println(emp);}
四、xml映射文件的使用
通过完成上述增删改查操作后,发现有一个很大的缺陷就是更新的时候必须全部属性更新,无法对个别属性进行更新,查询操作也同样如此,无法随意指定属性作为条件进行查询,因为EmpMapper中查询的条件写死了,必须按照那几个属性进行查询,少传或者多传参数会报错,因此为了解决这个缺陷采用xml映射文件:
如何配置xml映射文件:
有三条规范:
第一条规范:
首先根据mapper包创建配置文件:(必须要用/来分隔,这样就可以创建多级目录)注意名称需要和项目包名com.springboot_test1以及mapper包名mapper一致.
如下图:此处创建file名为com/springboot_test1/mapper,然后再创建一个名为EmpMapper.xml的文件即可。
然后复制如下代码到刚创建的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">
第二条规范:
xml映射文件中的namespace属性与Mapper接口的全限定名一致:获取接口的全限定名:copy reference
第三条规范:
sql语句中的id与Mapper接口中的方法名一致,并且ResultType为单条记录所封装的类型;select中的id就是接口中的方法名,对于resultType将这个实体类copy reference即可;
整体上就是当调用EmpMapper接口中的方法的时候,先去查找xml映射文件中namespace属性与这个接口全限定名相同的,然后找到id属性与方法名相同的sql语句,然后执行这条sql语句返回结果;
这样就配置完成xml映射文件。
五、动态sql语句
像如下这种的sql语句,直接就写死了,必须要传进去这些参数。但是如果想传递部分参数然后进行条件查询的话,此时就是动态sql语句(在xml映射文件中编写sql语句);
可以用以下方式来实现:<if> <where>(查询) <set>(更新)标签的使用:<where>是用于去除冗余的逗号等,可以进行自动判断;
<if>标签用于判断条件是否成立,使用test属性进行条件判断,如果条件为true那么则拼接sql。
动态查询操作:
EmpMapper中代码:注意有了xml映射文件,EmpMapper中方法前面就无需加响应注解了,只需要在xml映射文件中对应上方法名称以及resultType即可。想根据哪些属性查询就传入哪些属性。
//TODO 通过xml映射文件配置条件查询:就不用带注解了!!!;public List<Emp> list1(String name, Short gender, LocalDate begin,LocalDate end);
xml映射文件中代码:
<select id="list1" resultType="com.springboot_test1.pojo.Emp">select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_timefrom emp<where><if test="name!=null">name like concat('%',#{name},'%')</if><if test="gender!=null">and gender=#{gender}</if><if test="begin!=null and end!=null">and entrydate between #{begin} and #{end}</if></where>order by update_time desc</select>
test测试:用<where>标签的原因如下:
@Testpublic void testSelect_tiaojian1() {
// List<Emp> list=empMapper.list1("张",null,null,null);//但是如果将name设置为null之后,就会报错,因为用if语句,有了就拼接,没有就舍弃,// 这样name舍弃之后where后面多了一个and:select *from emp where and gender=? order by update_time desc//为了解决这个问题,引入mybatis中的标签:<where>;将xml映射文件中的select语句里面的where替换为<where>,会自动删除and;
// List<Emp> list=empMapper.list1(null,(short)1,null,null);
//此时相当于查询全部数据:List<Emp> list=empMapper.list1(null,null,null,null);System.out.println(list);}
动态更新操作:
EmpMapper中:
//TODO 动态更新员工信息,在xml映射文件中配置public void update2(Emp emp);//可以Alt加回车然后点击generate自动在xml文件中配置;
xml映射文件中:
<update id="update2">
# update emp where id=1,name="tom"......update emp<set><if test="username!=null">username=#{username},</if><if test="name!=null">name=#{name},</if><if test="gender!=null">gender=#{gender},</if><if test="image!=null">image=#{image},</if><if test="job!=null">job=#{job},</if><if test="entrydate!=null">entrydate=#{entrydate},</if><if test="deptId!=null">dept_id=#{deptId},</if><if test="updateTime!=null">update_time=#{updateTime}</if></set>where id = #{id}</update>
test测试:
@Test//测试更新方法,要求是id为22号数据username更新为Jerrygood,name更新为杰瑞棒,gender更新为2;// 采用xml映射文件以及动态更新sql语句,可以发现后面不需要更改的属性没有变成null;public void testUpdate2(){Emp emp=new Emp();emp.setId(22);emp.setUsername("Jerrygood");emp.setName("杰瑞棒");emp.setGender((short)2);emp.setUpdateTime(LocalDateTime.now());//这个是要更新的,每次改动数据要改成现在的时间;empMapper.update2(emp);}
批量删除操作:
此处使用<foreach>标签:
EmpMapper中:
//TODO 批量删除操作:是根据id号来删除,因为是多个id,所以一般用数组或者集合来接收;public void deleteByIds(List<Integer> ids);
xml映射文件中:
<!--批量删除员工操作:(18,19,20)
collection:所要遍历的集合:ids要和接口中定义的方法的参数相同
item:遍历出来的元素
separator:分隔符:用,分隔
open:遍历开始前拼接的sql片段:(
close:遍历开始后拼接的sql片段:)
--><delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach></delete>
</mapper>
test测试:
@Test //测试批量删除方法:public void testDeleteByIds(){List<Integer>ids=Arrays.asList(13,14,15);empMapper.deleteByIds(ids);}
以上就是mybatis基础用法以及细节。
相关文章:

Mybatis基础教程及使用细节
本篇主要对Mybatis基础使用进行总结,包括Mybatis的基础操作,使用注解进行增删改查的练习;详细介绍xml映射文件配置过程并且使用xml映射文件进行动态sql语句进行条件查询;为了简化java开发提高效率,介绍一下依赖&#x…...

10 分钟在K8s 中部署轻量级日志系统 Loki
转载至我的博客 https://www.infrastack.cn ,公众号:架构成长指南 Loki 是什么? Loki是由Grafana Labs开源的一个水平可扩展、高可用性,多租户的日志聚合系统的日志聚合系统。它的设计初衷是为了解决在大规模分布式系统中&#x…...

图像处理python基础
array 读取图片 tensor 模型预测 一般过程:读取数据np->tensor->model->result->np->画图 shape确保图像输入输出尺寸正确 读取图片 将在GPU上运行的tensor类型转变成在CPU上运行的np类型 三类计算机视觉任务的输入: 分类࿱…...

基于WordPress开发微信小程序2:决定开发一个wordpress主题
上一篇:基于WordPress开发微信小程序1:搭建Wordpress-CSDN博客 很快发现一个问题,如果使用别人的主题模板,多多少少存在麻烦,所以一咬牙,决定自己开发一个主题模板,并且开源在gitee上ÿ…...

[Python] 什么是网格搜索以及scikit-learn中GridSearch类的介绍和使用案例?
什么是网格搜索? 网格搜索是一种参数调优的方法,它可以帮助找到最佳的模型参数。在网格搜索中,我们先指定参数的候选值范围,然后枚举所有可能的参数组合,计算每个模型的性能指标(比如准确率、精确率等&…...

Linux-正则表达式
1.正则表达式的定义: 正则表达式通常用于判断语句中,使用字符串描述、匹配一系列符合某个规则的字符串。 正则表达式是由普通字符与元字符组成。 普通字符包括小写字母、数字、标点符号及一些其他符号。元字符是指在正则表达式中具有特殊意义的专用字符&…...

Java基础学习:System类和Static方法的实际使用
一、System类 1.在程序开发中,我们需要对这个运行的结果进行检验跟我们预判的结果是否一致,就会用到打印结果在控制台中显示出来使用到了System类。System类定义了一些和系统相关的属性和方法,它的属性和方法都是属于静态的,想使用…...

线性代数------矩阵的运算和逆矩阵
矩阵VS行列式 矩阵是一个数表,而行列式是一个具体的数; 矩阵是使用大写字母表示,行列式是使用类似绝对值的两个竖杠; 矩阵的行数可以不等于列数,但是行列式的行数等于列数; 1.矩阵的数乘就是矩阵的每个…...

Flutter 开发3:创建第一个Flutter应用
Step 1: 安装Flutter 1.1 下载Flutter SDK 首先,你需要访问Flutter官方网站下载最新的Flutter SDK。选择适合你操作系统的安装包。 $ cd ~/development $ unzip ~/Downloads/flutter_macos_2.2.3-stable.zip1.2 更新环境变量 接下来,你需要将Flutter…...
Linux中断下半部分:软中断,tasklet和工作队列
为什么要有下半部分 中断会打断其他程序,为了打断其他程序时间短,就需要中断处理程序快。执行中断处理程序后,相同中断不会触发,甚至所有中断都不能触发(设置IRQF_DISABLED,其他硬件与操作系统无法通信)中…...

Flink CEP实现10秒内连续登录失败用户分析
1、什么是CEP? Flink CEP即 Flink Complex Event Processing,是基于DataStream流式数据提供的一套复杂事件处理编程模型。你可以把他理解为基于无界流的一套正则匹配模型,即对于无界流中的各种数据(称为事件),提供一种组合匹配的…...

QSqlRelationalTableModel 关系表格模型
一、 1.1 QSqlRelationalTableModel继承自QSqlTableModel,并且对其进行了扩展,提供了对外键的支持。一个外键就是一个表中的一个字段 和 其他表中的主键字段之间的一对一的映射。例如,“studInfo”表中的departID字段对应的是“departments…...

JS和CSS实现的原生轮播图
JSCSS实现滑动轮播图 使用JS加CSS来实现的幻灯片,主要使用的是CSS的transform属性中的translate来实现,适合与用户交互的轮播图,展现轮播图的数量,用户可自由进行选择。 <!DOCTYPE html> <html lang"en">&…...

【微服务】skywalking自定义链路追踪与日志采集
目录 一、前言 二、自定义链路追踪简介 2.1 自定义链路追踪应用场景 2.2 链路追踪几个关键概念 三、skywalking 自定义链路追踪实现 3.1 环境准备 3.2 集成过程 3.2.1 导入核心依赖 3.2.2 几个常用注解 3.2.3 方法集成 3.2.4 上报追踪信息 四、skywalking 自定义日志…...
MYSQL基础问题
一.DBMS 是什么 DBMS(Database Management System),数据库管理系统,是一种操纵和管理 数据库的大型软件,用于建立、使用和维护数据库。对数据库进行统一的管理和 控制,以保证数据库的安全性和完整性。 二…...
SpringBoot使用Guava实现日志脱敏(含源码)
点击下载《SpringBoot使用Guava实现日志脱敏(含源码)》 1. 摘要 本文将介绍如何使用Google Guava库进行日志脱敏,保护敏感数据的安全。我们将详细解释脱敏的必要性,然后介绍如何使用Guava中的Strings、Maps和CharMatcher类来进行…...

数据结构—动态查找
动态查找介绍 1. 动态查找的引入:当查找表以线性表的形式组织时,若对查找表进行插入、删除或排序操作,就必须移动大量的记录,当记录数很多时,这种移动的代价很大。 2. 动态查找表的设计思想:表结构本身是…...
Tarjan算法学习笔记
目录 无向图的割点与桥 时间戳: 搜索树: 追溯值: 割边判定法则: 割点判定法则: 无向图的双连通分量 定理: 边双连通分量(e-DCC)的求法: e-DCC的缩点: 有向图的连通性 追…...
vue 项目涉及的焦点聚焦、格式化日期、判断是否为对象或数组、判断是否为空、深拷贝、节流、防抖
焦点聚焦 import Vue from vue // 插件对象(必须有 install 方法, 才可以注入到 Vue.use 中) export default {install () {Vue.directive(fofo, {inserted (el) {el el.querySelector(input)el.focus()}})} }格式化日期格式 export const formatDate (time) > {// 将xx…...

软件工程知识梳理6-运行和维护
软件维护需要的工作量很大,大型软件的维护成本高达开发成本的4倍左右。所以,软件工程的主要目的就是要提高软件的可维护性,减少软件维护所需要的工作量,降低软件系统的总成本。 定义:软件已经交付使用之后,…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...