【JavaEE进阶】——Mybatis操作数据库(使用注解和XML方式)
目录
🚩三层架构
🎈JDBC操作回顾
🚩什么是MyBatis
🚩MyBatis⼊⻔
🎈准备工作
📝创建⼯程
📝数据准备
🎈配置数据库连接字符串
🎈写持久层代码
🎈单元测试
🚩MyBatis的基础操作
🎈打印日志
🎈参数传递
🎈增(Insert)
📝返回主键(实现自增效果)
🎈删(delete)
🎈改(Update)
🎈查(Select)
📝起别名
📝结果映射
📝开启驼峰命名(推荐)
🚩MyBatis XML配置文件
🎈配置连接字符串和MyBatis
🎈写持久层代码
📝添加 mapper 接⼝
📝添加 UserInfoXMLMapper2.xml
📝查询所有⽤⼾的具体实现 :
📝单元测试
🎈增删改查操作
📝增(Insert)
📝删(Delete)
📝改(Update)
📝查(Select)
本节⽬标
- 1. 使⽤MyBatis完成简单的增删改查操作, 参数传递.
- 2. 掌握MyBatis的两种写法: 注解 和 XML⽅式
- 3. 掌握MyBatis 相关的⽇志配置
🚩三层架构
在应⽤分层学习时, 我们 了解到web应⽤程序⼀般分为三层,即:Controller、Service、Dao .
- 表现层:Controller 参数接收,参数校验,参数格式转换,结果格式转换,结果返回等等
- 业务逻辑层:Service 介于表现层和数据层之间,业务逻辑相关的处理
- 数据层:Dao 与数据相关的,数据的增删改查
之前的案例中,请求流程如下:浏览器发起请求, 先请求Controller, Controller接收到请求之后, 调⽤ Service进⾏业务逻辑处理, Service再调⽤Dao, 但是Dao层的数据是Mock的, 真实的数据应该从数据库中读取.我们学习MySQL数据库时,已经学习了JDBC来操作数据库, 但是JDBC操作太复杂了.
🎈JDBC操作回顾
我们先来回顾⼀下 JDBC 的操作流程:
- 1. 创建数据库连接池 DataSource
- 2. 通过 DataSource 获取数据库连接 Connection
- 3. 编写要执⾏带 ? 占位符的 SQL 语句
- 4. 通过 Connection 及 SQL 创建操作命令对象 Statement
- 5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
- 6. 使⽤ Statement 执⾏ SQL 语句
- 7. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
- 8. 处理结果集
- 9. 释放资源
展⽰了通过 JDBC 的 API 向数据库中添加⼀条记录,修改⼀条记录,查询⼀条记录的操作。从上述的操作流程中可以看出,对于JDBC来说,整个操作非常的繁琐,不但要拼接每一个参数,而且还要按照模板代码的方式,一步步的操作数据库,并且在每次操作完,还要手动关闭连接等,而所有的这些操作步骤都需要在每个方法中重复书写,那有没有一种方法,可以更简单,更方便的操作数据库呢?答案是肯定的,这就是我们要学习 MyBatis 的真正原因,它可以帮助我们更⽅便、更快速的操作数据库.
🚩什么是MyBatis
在上⾯我们提到⼀个词:持久层• 持久层:指的就是持久化操作的层, 通常指数据访问层(dao), 是⽤来操作数据库的
简单来说 MyBatis是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库工具,接下来,我们就通过一个入门程序,让大家感受一下通过MyBatis如何来操作数据库
🚩MyBatis⼊⻔
Mybatis操作数据库的步骤:
- 1. 准备⼯作(创建springboot⼯程、数据库表准备、实体类)
- 2. 引⼊Mybatis的相关依赖,配置Mybatis(数据库连接信息)
- 3. 编写SQL语句(注解/XML)
- 4. 测试
🎈准备工作
📝创建⼯程

Mybatis 是⼀个持久层框架, 具体的数据存储和数据操作还是在MySQL中操作的, 所以需要添加MySQL驱动。
<!--Mybatis 依赖包--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!--mysql驱动包-->
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
</dependency>
📝数据准备
-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`username` VARCHAR ( 127 ) NOT NULL,`password` VARCHAR ( 127 ) NOT NULL,`age` TINYINT ( 4 ) NOT NULL,`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',`phone` VARCHAR ( 15 ) DEFAULT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now(),PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
-- 添加⽤⼾信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );
package com.example.mybatis_test.model;import lombok.Data;import java.util.Date;@Data
public class UserInfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;private Integer deleteFlag;private Date createTime;private Date updateTime;
}
🎈配置数据库连接字符串
# 数据库连接配置
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
注意事项:如果使⽤ MySQL 是 5.x 之前的使⽤的是"com.mysql.jdbc.Driver",如果是⼤于 5.x 使⽤的是“com.mysql.cj.jdbc.Driver”.
🎈写持久层代码
package com.example.mybatis_test.mapper;import com.example.mybatis_test.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface UserInfoMapper2 {//查询所有用户的信息@Select("select * from userinfo")List<UserInfo>getUserInfoAll();
}
Mybatis的持久层接⼝规范⼀般都叫 XxxMapper
- @Mapper注解:表⽰是MyBatis中的Mapper接⼝ ,程序运行时,框架会自动生成接口的实现类对象(代理对象),并交给Spring的IOC容器管理.(也就是在程序运行的时候,框架会自动生成UserInfoMapper2接口,然后交给了spring的ioc容器中让spring进行管理,等需要了就注入)
- @Select注解:代表的就是select查询,也就是注解对应方法的具体实现内容(而select就是执行sql语句,注解里面的内容就是具体实现内容)
🎈单元测试




package com.example.mybatis_test.mapper;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class UserInfoMapper2Test {@Testvoid getUserInfoAll() {}
}
此时的测试单元类就自动生成了,再src/test/java/Mapper里面自动生成了测试类。
package com.example.mybatis_test.mapper;import com.example.mybatis_test.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;import static org.junit.jupiter.api.Assertions.*;@SpringBootTest
class UserInfoMapper2Test {@Autowiredprivate UserInfoMapper2 userInfoMapper2;@Testvoid getUserInfoAll() {List<UserInfo>userInfos=userInfoMapper2.getUserInfoAll();for (UserInfo userInfo:userInfos) {System.out.println(userInfo);}}
}


🚩MyBatis的基础操作
🎈打印日志
#配置mybatis日志,为了后续观察sql语句的执行
mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- ①: 查询语句 preparing:select*from userinfo
- ②: 传递参数及类型 Parameters
- ③: SQL执⾏结果 cloums以下
🎈参数传递
#{}动态参数传递
//查询id=4的用户@Select("select * from userinfo where id=#{id}")UserInfo queryById(Integer id);
@Testvoid queryById() {UserInfo userInfo=userInfoMapper2.queryById(4);System.out.println(userInfo);}
🍭控制台结果

也可以通过 @Param , 设置参数的别名 , 如果使⽤ @Param 设置别名, #{...}⾥⾯的属性名必须和 @Param 设置的⼀样

🎈增(Insert)
//增加一个用户@Insert("insert into userinfo (username,`password`,age,gender) values" +"(#{username},#{password},#{age},#{gender})")Integer insert(UserInfo userInfo);
如果语句过长,我们可以直接敲回车,idea会自动给你换行。
🍭添加测试样例
@Testvoid insert() {UserInfo userInfo=new UserInfo();userInfo.setUsername("zyf");userInfo.setPassword("1005");userInfo.setAge(20);userInfo.setGender(1);Integer count=userInfoMapper2.insert(userInfo);System.out.println(count);}
🍭控制台结果
如果设置了 @Param 属性, #{...} 需要使⽤ 参数.属性 来获取//增加一个用户@Insert("insert into userinfo (username,`password`,age,gender) values" +"(#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender})")Integer insert(@Param("userinfo") UserInfo userInfo);

📝返回主键(实现自增效果)
自增id @Options(useGeneratedKeys = true, keyProperty = "id")
- useGeneratedKeys:这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据库内 部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动递增字 段),默认值:false.
- • keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回值或insert 语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)
Insert 语句默认返回的是 受影响的⾏数但有些情况下, 数据插⼊之后, 还需要有后续的关联操作, 需要获取到新插⼊数据的id⽐如订单系统当我们下完订单之后, 需要通知物流系统, 库存系统, 结算系统等, 这时候就需要拿到订单ID如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解![]()
![]()
注意: 设置 useGeneratedKeys=true 之后, ⽅法返回值依然是受影响的⾏数, ⾃增id 会设置在上 述 keyProperty 指定的属性中.
🎈删(delete)
📝使用注解:
@Delete("delete from userinfo where id=#{id}")Integer delete(Integer id);
📝添加测试样例
此时的表中就删除了id=4的用户。
🎈改(Update)
📝使用注解
//更新一个用户的姓名@Update("update userinfo set username=#{username} where id=#{id}")Integer update(String username,Integer id);
📝添加测试样例
@Testvoid update() {Integer count=userInfoMapper2.update("zyf",5);System.out.println(count);}

🎈查(Select)
@Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")List<UserInfo> queryAllUser();
📝添加测试样例
@Testvoid queryAllUser() {List<UserInfo>infoList=userInfoMapper2.queryAllUser();for (UserInfo userInfo:infoList) {System.out.println(userInfo);}}
原因分析:当⾃动映射查询结果时, MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略⼤⼩写) 。 这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性
但是有三个属性和表的列名不一致,就不会进行赋值。
解决办法:
- 1. 起别名
- 2. 结果映射
- 3. 开启驼峰命名
MyBatis 会根据⽅法的返回结果进⾏赋值.
- ⽅法⽤对象 UserInfo接收返回结果, MySQL 查询出来数据为⼀条, 就会⾃动赋值给对象.
- ⽅法⽤List<UserInfo>接收返回结果, MySQL 查询出来数据为⼀条或多条时, 也会⾃动赋值给List.
- 但如果MySQL 查询返回多条, 但是⽅法使⽤UserInfo接收, MyBatis执⾏就会报错
📝起别名
@Select("select id, username, `password`, age, gender, phone, delete_flag as deleteFlag, create_time as createTime, update_time as updateTime from userinfo")List<UserInfo> queryAllUser2();
SQL语句太⻓时, 使⽤加号 + 进⾏字符串拼接(直接按回车idea自动给你换行)

@Testvoid queryAllUser2() {List<UserInfo>infoList=userInfoMapper2.queryAllUser2();for (UserInfo userInfo:infoList) {System.out.println(userInfo);}}

📝结果映射
@Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")@Results({@Result(column = "delete_flag",property = "deleteFlag"),@Result(column = "create_time",property = "createTime"),@Result(column = "update_time",property = "updateTime")})List<UserInfo> queryAllUser();
使⽤ id 属性给该 Results 定义别名, 使⽤ @ResultMap 注解来复⽤其他定义的 ResultMap



📝开启驼峰命名(推荐)
通常数据库列使⽤蛇形命名法进⾏命名(下划线分割各个单词), Java 属性⼀般遵循驼峰命名法约定.驼峰命名规则: abc_xyz => abcXyz
- • 表中字段名:abc_xyz
- • 类中属性名:abcXyz
为了在这两种命名⽅式之间启⽤⾃动映射,需要将 mapUnderscoreToCamelCase 设置为 true。mybatis:configuration:map-underscore-to-camel-case: true #配置驼峰⾃动转换
🍭配置驼峰自动转换
//查询所有用户的信息@Select("select * from userinfo")List<UserInfo>getUserInfoAll();
🍭添加测试样例
@Testvoid getUserInfoAll() {List<UserInfo>userInfos=userInfoMapper2.getUserInfoAll();for (UserInfo userInfo:userInfos) {System.out.println(userInfo);}}
相比于起别名和结果映射,开启驼峰命名更加的简单,只需要再配置文件中配置一下,即可。
🚩MyBatis XML配置文件
上⾯学习了注解的⽅式, 接下来我们学习XML的⽅式使⽤Mybatis的注解⽅式,主要是来完成⼀些简单的增删改查功能. 如果需要实现复杂的SQL功能,建议使⽤XML来配置映射语句,也就是将SQL语句写在XML配置⽂件中.
MyBatis XML的⽅式需要以下两步:
- 1. 配置数据库连接字符串和MyBatis
- 2. 写持久层代码
🎈配置连接字符串和MyBatis
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:mapper-locations: classpath:mapper/**Mapper.xml
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: 105528clzyf.driver-class-name: com.mysql.cj.jdbc.Driver
#配置mybatis日志,为了后续观察sql语句的执行
mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
##配置驼峰⾃动转换map-underscore-to-camel-case: true
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件mapper-locations: classpath:mapper/UserInfoMapper2.xml
配置mybatis.xml文件,我们需要在src/main/resources/mapper目录下创建xml文件。
🎈写持久层代码
持久层代码分两部分
- 1. ⽅法定义 Interface
- 2. ⽅法实现: UserInfoMapper2.xml

📝添加 mapper 接⼝
package com.example.mybatis_test.mapper;import com.example.mybatis_test.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface UserInfoXmlMapper2 {List<UserInfo>queryAllUser();
}
📝添加 UserInfoXMLMapper2.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="com.example.mybatis_test.mapper.UserInfoXmlMapper2"></mapper>
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件mapper-locations: classpath:mapper/UserInfoMapper2.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="com.example.mybatis_test.mapper.UserInfoXmlMapper2"><select id="queryAllUser">select username,`password`,age,gender,phone, from userinfo</select>
</mapper>
以下是对以上标签的说明:
- • <mapper> 标签:需要指定 namespace 属性,表⽰命名空间,值为 mapper 接⼝的全限定名,包括全包名.类名。
- • <select> 查询标签:是⽤来执⾏数据库的查询操作的:
◦ id :是和 Interface (接⼝)中定义的⽅法名称⼀样的 ,表⽰对接⼝的具体实现⽅法。◦ resultType :是返回的数据类型,也就是开头我们定义的实体类.

📝单元测试
@SpringBootTest
class UserInfoMapper2Test {@Autowiredprivate UserInfoMapper2 userInfoMapper2;@Testvoid getUserInfoAll() {List<UserInfo>userInfos=userInfoMapper2.getUserInfoAll();for (UserInfo userInfo:userInfos) {System.out.println(userInfo);}}
}
🎈增删改查操作
📝增(Insert)
///增Integer insertUser(UserInfo userInfo);
<insert id="insertUser">insert into userinfo (username,`password`,age,gender,phone)values (#{username},#{password},#{age},#{gender},#{phone})</insert>
///增Integer insertUser(@Param("userinfo") UserInfo userInfo);
<insert id="insertUser">insert into userinfo (username,`password`,age,gender,phone)values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})</insert>

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">insert into userinfo (username,`password`,age,gender,phone)values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})</insert>

📝删(Delete)
🍭UserInfoMapper接⼝
//删Integer deleteUser(Integer id);
🍭UserInfoMapper.xml实现:
<delete id="deleteUser">delete from userinfo where id=#{id};</delete>
🍭测试
@Testvoid deleteUser() {Integer count=userInfoXmlMapper2.deleteUser(2);System.out.println(count);}

📝改(Update)
//改Integer updateUser(String username,Integer id);
🍭UserInfoMapper.xml实现:
<update id="updateUser">update userinfo set username=#{username} where id=#{id}</update>
🍭测试
@Testvoid updateUser() {Integer count=userInfoXmlMapper2.updateUser("zzzzz",7);System.out.println(count);}

📝查(Select)
//查List<UserInfo>selectUser();
🍭UserInfoMapper.xml实现:
<select id="selectUser">select id, username,`password`, age, gender, phone, delete_flag,create_time, update_time from userinfo</select>
🍭测试
@Testvoid selectUser() {List<UserInfo>infoList=userInfoXmlMapper2.selectUser();for (UserInfo userInfo:infoList) {System.out.println(userInfo);}}
解决办法和注解类似
- 1. 起别名
- 2. 结果映射
- 3. 开启驼峰命名
其中1,3的解决办法和注解⼀样,不再多说, 接下来看下xml如果来写结果映射
🍭结果映射
<resultMap id="BaseMap" type="com.example.mybatis_test.model.UserInfo"><id column="id" property="id"></id><result column="delete_flag" property="deleteFlag"></result><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result></resultMap><select id="selectUser" resultMap="BaseMap">select id, username,`password`, age, gender, phone, delete_flag,create_time, update_time from userinfo</select>
注解方式和XML方式结果映射区别
六一快乐~今天吃了自助餐,几年没有穿裙子今天买了个裙子,给张老师买了白色上袖为it文化节准备上台。
相关文章:

【JavaEE进阶】——Mybatis操作数据库(使用注解和XML方式)
目录 🚩三层架构 🎈JDBC操作回顾 🚩什么是MyBatis 🚩MyBatis⼊⻔ 🎈准备工作 📝创建⼯程 📝数据准备 🎈配置数据库连接字符串 🎈写持久层代码 🎈单…...

【数据结构】六种排序实现方法及区分比较
文章目录 前言插入排序希尔排序选择排序堆排序快速排序冒泡排序总结 前言 众所周知,存在许多种排序方法,作为新手,最新接触到的就是冒泡排序,这种排序方法具有较好的教学意义,但是实用意义不高,原因就在于…...

QT之QTableWidget详细介绍
本文来自于学习QT时遇到QTableWidget类时进行总结的知识点,涵盖了QTableWidget主要函数。本人文笔有限,欢迎大家评论区讨论。 一、QTableWidget介绍 QTableWidget 类是 Qt 框架中的一个用于展示和编辑二维表格数据的控件。它是对 QTableView 和 QStand…...

mac电脑安卓设备文件传输助手:MacDroid pro 中文激活版
MacDroid Pro是一款专为Mac电脑和Android设备设计的软件,旨在简化两者之间的文件传输和数据管理,双向文件传输:支持从Mac电脑向Android设备传输文件,也可以将Android设备上的文件轻松传输到Mac电脑上。完整的文件访问和管理&#…...

车流量监控系统
1.项目介绍 本文档是对于“车流量检测平台”的应用技术进行汇总,适用于此系统所有开发,测试以及使用人员,其中包括设计背景,应用场景,系统架构,技术分析,系统调度,环境依赖…...

LAMP集群分布式实验报告
前景: 1.技术成熟度和稳定性: LAMP架构(Linux、Apache、MySQL、PHP)自1998年提出以来,经过长时间的发展和完善,已经成为非常成熟和稳定的Web开发平台。其中,Linux操作系统因其高度的灵活性和稳…...

vue3中函数必须有返回值么?
在 Vue 3 中,特别是涉及到Composition API的使用时,setup() 函数确实必须有返回值。setup() 函数是组件的入口点,它的返回值会被用来决定哪些数据和方法是可被模板访问的。返回的对象中的属性和方法可以直接在模板中使用。如果setup()没有返回…...

经常用到的函数
创建文件夹和删除文件夹的函数 def make_dirs(*dirs):for new_dir in dirs:if not os.path.exists(new_dir):try:os.makedirs(new_dir)except RuntimeError:return Falsereturn Truedef remove_files(file_path_list):""" 删除列表中指定路径文件Args:file_pat…...

vue3学习(六)
前言 接上一篇学习笔记,今天主要是抽空学习了vue的状态管理,这里学习的是vuex,版本4.1。学习还没有学习完,里面有大坑,难怪现在官网出的状态管理用Pinia。 一、vuex状态管理知识点 上面的方式没有写全,还有…...

[数据集][目标检测]猫狗检测数据集VOC+YOLO格式8291张2类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):8291 标注数量(xml文件个数):8291 标注数量(txt文件个数):8291 标注…...

简单模拟实现shell(Linux)
目录 前言 展示效果 实现代码 前言 该代码模拟了shell的实现,也就是解析类似于“ls -a -l"的命令,当我们启动我们自己写的shell的可执行程序时,我们输入"ls"的命令,也可以展示出在shell中输入&…...

SQL深度解析:从基础到高级应用
SQL(Structured Query Language)是用于管理关系型数据库的语言,广泛应用于数据管理、分析和查询。本文将详细介绍SQL的基础知识、高级特性以及一些常见的代码示例,帮助您全面掌握SQL的应用。 一、SQL基础语法 数据库操作 创建数据…...

乡村振兴与脱贫攻坚相结合:巩固拓展脱贫攻坚成果,推动乡村全面振兴,建设更加美好的乡村生活
目录 一、引言 二、巩固拓展脱贫攻坚成果 1、精准施策,确保稳定脱贫 2、强化政策支持,巩固脱贫成果 3、激发内生动力,促进持续发展 三、推动乡村全面振兴 1、加快产业发展,增强乡村经济实力 2、推进乡村治理体系和治理能力…...

[AI Google] Google I/O 2024: 为新一代设计的 I/O
编辑注:以下是 Sundar Pichai 在 I/O 2024 上讲话的编辑版,并包含了更多在舞台上宣布的内容。查看我们收藏中的所有公告。 Google 完全进入了我们的 Gemini 时代。 在开始之前,我想反思一下我们所处的这一刻。我们已经在 AI 上投资了十多年…...

CentOS配置DNS
1.打开/etc/resolv.conf文件 sudo vi /etc/resolv.conf2.添加配置 nameserver 114.114.114.1143.保存并关闭文件。 4.为了确保配置生效,重启网络服务或重启系统。例如: 重启网络: sudo systemctl restart network重启系统: …...

ArcGIS空间数据处理、空间分析与制图;PLUS模型和InVEST模型的原理,参量提取与模型运行及结果分析;土地利用时空变化以及对生态系统服务的影响分析
工业革命以来,社会生产力迅速提高,人类活动频繁,此外人口与日俱增对土地的需求与改造更加强烈,人-地关系日益紧张。此外,土地资源的不合理开发利用更是造成了水土流失、植被退化、水资源短缺、区域气候变化、生物多样性…...

Linux基于V4L2的视频捕捉
简介 linux环境使用V4l2实现摄像头捕捉,界面流畅播放并可以保存图片到本地。 代码 void VideoCapture::run() {qDebug() << "VideoCapture start";// 打开设备int fd open("/dev/video0", O_RDWR);if(fd < 0){qDebug("video设…...

ECS搭建2.8版本的redis
要在ECS(Elastic Compute Service)上手动搭建Redis 2.8版本,你可以按照以下步骤操作: 步骤1:更新系统和安装依赖 首先,登录到你的ECS实例,确保系统是最新的并安装必要的依赖包: s…...

[机器学习]GPT LoRA 大模型微调,生成猫耳娘
往期热门专栏回顾 专栏描述Java项目实战介绍Java组件安装、使用;手写框架等Aws服务器实战Aws Linux服务器上操作nginx、git、JDK、VueJava微服务实战Java 微服务实战,Spring Cloud Netflix套件、Spring Cloud Alibaba套件、Seata、gateway、shadingjdbc…...

代码随想录算法训练营Day24|216.组合总和III、17.电话号码的字母组合
组合总和III 216. 组合总和 III - 力扣(LeetCode) 思路和昨日的组合题类似,但注意对回溯算法中,收获时的条件需要写对,path的长度要为k的同时,path中元素总和要为n。 class Solution { public:vector<…...

【Python系列】Python 中方法定义与方法调用详解
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Java 基础面试300题 (201-230)
Java 基础面试300题 (201-230) 201.下面代码片段的输出是什么? Predicate<Integer> numberChecker (num)–> num > 20; int input 10; System.out.println(input” greater than 20–”numberChecker.test(input)); //Line 1…...

Go-知识并发控制Context
Go-知识并发控制Context 1. 介绍2. 实现原理2.1 接口定义2.2 Deadline()2.3 Done()2.4 Err()2.5 Value() 3. 空 context4. cancelCtx4.1 Done()4.2 Err()4.3 cancel()4.4 WithCancel4.5 例子4.6 总结 5. timerCtx5.1 Deadline5.2 cancel5.3 WithDeadline5.4 WithTimeout5.5 例子…...

Vue + Nodejs + socket.io 实现聊天
Vue 代码 // 安装 socket.io-clientnpm i socket.io-clientimport io from socket.io-client;mounted () {// * location.origin 表示你的 socket 服务地址// * /XXXX/socket.io 表示 你的 socket 在服务器配置的 访问地址let socket io(location.origin, {path: "/XX…...

cocos creator 3.x实现手机虚拟操作杆
简介 在许多移动游戏中,虚拟操纵杆是一个重要的用户界面元素,用于控制角色或物体的移动。本文将介绍如何在Unity中实现虚拟操纵杆,提供了一段用于移动控制的代码。我们将讨论不同类型的虚拟操纵杆,如固定和跟随,以及如…...

【数据分享】中国电力年鉴(2004-2022)
大家好!今天我要向大家介绍一份重要的中国电力统计数据资源——《中国电力年鉴》。这份年鉴涵盖了从2004年到2022年中国电力统计全面数据,并提供限时免费下载。(无需分享朋友圈即可获取) 数据介绍 自1993年首次出版以来…...

两个数组的交集Ⅱ-力扣
想到的解法是使用两个map来进行记录,mp1用来统计num1中每个元素出现的次数。当nums2的元素能够在mp1中查找到时,将这个元素添加到mp2,按照这个规则统计得到nums2和nums1重复的元素,mp2中的value记录了nums2中这个元素出现的次数最…...

【TCP协议中104解析】wireshark抓取流量包工具,群殴协议解析基础
Tcp ,104 ,wireshark工具进行解析 IEC104 是用于监控和诊断工业控制网络的一种标准,而 Wireshark则是一款常用的网络协议分析工具,可以用干解析TEC104 报文。本文将介绍如何使用 Wireshark解析 IEC104报文,以及解析过 程中的注意事项。 一、安…...

[个人笔记] 记录docker-compose使用和Harbor的部署过程
容器技术 第三章 记录docker-compose使用和Harbor的部署过程 容器技术记录docker-compose使用和Harbor的部署过程Harborhttps方式部署:测试环境部署使用自签名SSL证书https方式部署:正式环境部署使用企业颁发的SSL证书给Docker守护进程添加Harbor的SSL证…...

详细介绍运算符重载函数,清晰明了
祝各位六一快乐~ 前言 1.为什么要进行运算符重载? C中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。这时就必须在C中重新定义这些运算符ÿ…...