Mybatis学习笔记注解/xml映射/动态SQL%%%Mybatis教程
介绍
- Mybatis 是一款优秀的持久层框架,用于简化 JDBC 的开发
 
MyBatis中文网
 
Mybatis 入门
快速入门
- 步骤
 
- 创建 SpringBoot 工程、数据库表 user、实体类 User
 - 引入 Mybatis 相关依赖,配置 Mybatis(数据库连接信息)
 - 编写 SQL 语句(注解/XML)
 
项目创建


创建的项目的 pom.xml 如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demoMybatis</artifactId><version>0.0.1-SNAPSHOT</version><name>demoMybatis</name><description>demoMybatis</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.2</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>3.0.2</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
 
引入了这三个依赖:

 
数据库表格创建

代码如下:
CREATE DATABASE mybatis;
USE mybatis;CREATE TABLE USER(id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT 'ID',NAME VARCHAR(100) COMMENT '姓名',age TINYINT UNSIGNED COMMENT '年龄',gender TINYINT UNSIGNED COMMENT '性别, 1:男, 2:女',phone VARCHAR(11) COMMENT '手机号'
) COMMENT '用户表';INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'白眉鹰王',55,'1','18800000000');
INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'金毛狮王',45,'1','18800000001');
INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'青翼蝠王',38,'1','18800000002');
INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'紫衫龙王',42,'2','18800000003');
INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'光明左使',37,'1','18800000004');
INSERT INTO USER(id, NAME, age, gender, phone) VALUES (NULL,'光明右使',48,'1','18800000005');
 
 
创建 User 实体类

实体类 User 中的属性与数据库表格中的字段是一一对应的
在实体类属性定义的时候使用相关数据类型的包装类型
再创建有参无参构造、getter/setter 方法以及 toString 方法
package com.example.pojo;public class User {/*实体类 User 中的属性与数据库表格中的字段是一一对应的在实体类属性定义的时候使用相关数据类型的包装类型*/private Integer id;private String name;private Short age;private Short gender;//生成getter和setter方法和toString方法以及有参无参构造public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Short getAge() {return age;}public void setAge(Short age) {this.age = age;}public Short getGender() {return gender;}public void setGender(Short gender) {this.gender = gender;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", gender=" + gender +'}';}public User() {}public User(Integer id, String name, Short age, Short gender) {this.id = id;this.name = name;this.age = age;this.gender = gender;}
}
 
 
配置 Mybatis

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=123456
 
数据库的名字为 mybatis,数据库的密码为 123456
要依据具体情况修改
 
编写 SQL 语句(这里使用注解的方式)
- 创建接口
 

代码如下:
package com.example.mapper;import com.example.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper //在运行时,会自动生成该接口的实现类对象(代理对象),并将该对象交给IOC容器管理
public interface UserMapper {//查询全部用户信息//全部用户信息使用list集合@Select("select * from user")public List<User> list();
}
 
 
代码测试

在这个测试类中编写如下代码:
package com.example;import com.example.mapper.UserMapper;
import com.example.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;/*** 这是SpringBoot工程自带的一个测试类*/@SpringBootTest//SpringBoot整合单元测试的注解
class DemoMybatisApplicationTests {/*写一个测试方法来进行测试查询所有用户的信息来调用UserMapper接口中的list方法UserMapper是一个接口,不能直接new接口但是,在Usermapper接口上加了Mapper注解,会自动生成代理对象*///所以直接声明一个UserMapper的对象,再加上注解进行依赖注入@Autowiredprivate UserMapper userMapper;@Testpublic void testListUser(){//直接调用方法进行查询List<User> userList = userMapper.list();//进行遍历输出userList.stream().forEach(user ->{System.out.println(user);});}}
 
结果如下则成功
在 IDE 写的 sql 语句如果表名爆红
然后右侧就会加载出相关数据库的表格信息
JDBC 介绍
- JDBC 是使用 Java 语言操作关系型数据库的一套 API
 
JDBC,全称Java DataBase Connectivity(java数据库连接),是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问。它是由一组用java语言编写的类和接口组成,是sun公司制定的一套接口(interface),接口都有调用者和实现者。JDBC为程序开发人员提供了一组用于实现对数据库访问的JDBCAPI,并支持SQL语言,是sun开发的一套数据库访问编程接口,是一种SQL级的API。
JDBC的作用在于降低了程序的耦合度,提高了程序的扩展力。它通过驱动程序管理类(DriverManager)这个JDBC的管理类,作用于用户和驱动程序之间,提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
利用JDBC可以将JAVA代码连接到多种数据库,如oracle、DB2、SQLServer、MYSQL等,从而实现对数据库中的数据操作的目的。同时,JDBC具有很好的跨平台特性,使用JDBC编写的数据库应用程序可以在任何支持java的平台上运行,而不必在不同的平台上编写不同的应用程序。
Java、MySQL、JDBC、MyBatis和MyBatis Plus之间的关系、联系和区别如下:
- Java:Java是一种广泛使用的编程语言,它最初是由Sun Microsystems开发,现在由Oracle公司进行维护和发布。Java提供了一种平台无关的编程方式,使得开发人员可以编写一次代码,然后在任何支持Java的平台上运行。
 - MySQL:MySQL是一种流行的开源关系数据库管理系统(RDBMS),它使用SQL(结构化查询语言)作为其查询语言。MySQL具有高性能、可靠性和易于使用的特点,被广泛用于各种应用程序和网站。
 - JDBC:Java Database Connectivity(JDBC)是Java提供的一套用于和数据库对接的API。它提供了一种标准的接口,使得Java应用程序可以通过JDBC连接到各种关系数据库。MyBatis框架则是在此基础上进行了进一步的封装和简化。
 - MyBatis:MyBatis是一个流行的Java持久层框架,它封装了JDBC,使得开发人员可以更加方便地与数据库进行交互。MyBatis通过配置文件来定义SQL语句,这使得SQL语句可以与Java代码分离,更易于维护和修改。
 - MyBatis Plus:MyBatis Plus是MyBatis的增强工具,它在MyBatis的基础上提供了更多的功能和简化的操作。MyBatis Plus支持MyBatis的所有特性,并提供了基本的CRUD(创建、读取、更新、删除)功能,不需要开发人员自己编写SQL语句。此外,MyBatis Plus还引入了条件构造器(Querydsl),可以方便地构造复杂的查询条件。
 
总结起来,Java是编程语言,MySQL是数据库管理系统,JDBC是Java和MySQL之间的连接桥梁,而MyBatis和MyBatis Plus是在JDBC基础上进一步封装和简化的持久层框架。
JDBC 的代码使用就不需要详细掌握了
数据库连接池
- 数据库连接池 
- 数据库连接池是一个容器,负责分配、管理数据库连接
 - 允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
 - 释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏
 
 - 优势 
- 资源重用
 - 提升系统响应速度
 - 避免数据库连接遗漏
 
 
数据库连接池是计算机技术中的一种特殊池,用于存储和复用数据库连接。我们可以将其类比为现实生活中的游泳池。
在日常生活中,如果我们想要游泳,通常需要去游泳池。游泳池为我们提供了方便的游泳场所,并节省了我们每一次都必须挖掘一个新的泳池的费用和时间。池中的水可以被不同的人共享,高效地利用了水资源。
类似地,当我们需要与数据库进行交互时,我们通常需要创建数据库连接。创建数据库连接需要消耗计算资源和时间,而且如果每个请求都创建新的数据库连接,系统性能会大大降低。这时,数据库连接池就发挥作用了。
数据库连接池就像一个有多个泳道的游泳池。每个泳道都像一个数据库连接,而泳道中的水就像数据库连接的资源。这些资源被多个用户共享,而不是每个用户都创建新的资源。这样,我们就可以更高效地利用系统资源,提高系统性能。
具体来说,当我们需要与数据库交互时,我们从数据库连接池中获取一个可用的数据库连接,就像从泳道中借一个游泳圈一样。用完后,我们把这个连接放回连接池中,就像把游泳圈还回泳道一样。如果连接池中没有可用的连接,那么将会自动创建新的连接。就像如果所有的游泳圈都被借走了,那么游泳池管理员会再放入一些新的游泳圈。
同时,数据库连接池还可以对连接进行管理和监控。比如当一个连接被使用时,连接池可以记录这个连接的创建时间、最近一次使用时间等信息,并在需要时自动关闭那些长时间未被使用的连接,释放系统资源。就像游泳池管理员会根据泳道的占用情况来关闭那些没有人使用的泳道,节省水资源。
因此,数据库连接池通过复用数据库连接、管理和监控连接等作用,提高了系统性能和资源利用率。
在数据库连接池中,如果所有的连接都被占满了,有以下几种解决办法:
- 等待:如果所有的连接都在被高频率地使用,但是并没有空闲连接,那么你可以选择等待,直到有连接空出来。
 - 创建新的连接池:如果你需要更多的连接,你可以创建新的连接池。
 - 优化连接使用:在连接池中,如果连接被占满了,也可以通过优化连接使用来进行解决。比如可以对连接进行分类,对不同类型的连接进行管理和复用,以更高效地利用系统资源。
 因此,当游泳池中的泳道被占满了时,我们可以选择等待、提高泳姿或者寻找其他泳池。而在数据库连接池中,我们可以选择等待、创建新的连接池或者优化连接使用。

不同的编程语言和数据库系统有不同的默认连接池。以下是一些常见的默认连接池:
- Java语言中,使用JDBC连接数据库时,如果没有指定连接池,则默认使用的是“c3p0”或者“HikariCP”连接池。其中,HikariCP在Spring Boot 2.x版本之后被选为默认的数据库连接池。
 - MySQL的默认连接池是“c3p0”,可以通过在配置文件中指定“default-pool-size”参数来设置默认的最大连接数。
 - PostgreSQL的默认连接池是“yadcf”,也可以使用第三方的连接池如“pgbouncer”来作为默认的连接池。
 - Oracle数据库的默认连接池是“Generic”类型的,可以通过在配置文件中指定“MAX_POOL_SIZE”参数来设置默认的最大连接数。
 
需要注意的是,默认连接池可能因不同的版本和配置而有所不同,如果需要使用自定义的连接池,则需要在配置中进行相应的设置和指定。
切换数据库连接池
 
Lombok

引入 Lombok 依赖才能使用 Lombo 注解
        <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
 

这个时候,在原先的实体类中,注释掉 setter、getter、toString、构造方法
使用 Data 注解即可
运行结果依旧正确:
 
Mybatis 基础操作
准备工作
- 准备数据库 emp
 - 创建一个新的 SpringBoot 工程,选择引入对应的起步依赖
 - aapplication.properties 引入数据库连接信息
 - 创建对应的实体类 Emp
 - 准备 Mapper 接口 EmpMapper
 
- 创建数据库表格
 
-- 部门管理
create table dept(id int unsigned primary key auto_increment comment '主键ID',name varchar(10) not null unique comment '部门名称',create_time datetime not null comment '创建时间',update_time datetime not null comment '修改时间'
) comment '部门表';insert into dept (id, name, create_time, update_time) values(1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()), (4,'就业部',now(),now()),(5,'人事部',now(),now());-- 员工管理
create table emp (id int unsigned primary key auto_increment comment 'ID',username varchar(20) not null unique comment '用户名',password varchar(32) default '123456' comment '密码',name varchar(10) not null comment '姓名',gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',image varchar(300) comment '图像',job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',entrydate date comment '入职时间',dept_id int unsigned comment '部门ID',create_time datetime not null comment '创建时间',update_time datetime not null comment '修改时间'
) comment '员工表';INSERT INTO emp(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES(1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),(2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),(3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),(4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),(5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),(6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),(7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),(8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),(9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),(10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),(11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),(12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),(13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),(14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),(15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),(16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),(17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
 
- 创建项目、导入依赖
 



- 引入数据库链接信息
 

- 创建对应的实体类 Emp
 

使用驼峰命名法
- 准备 Mappe 接口
 

 
删除
编写 SQ 语句

在这里,@Delete后面写的是“delete from emp where id = #{id}”;而不是“delete from emp where id = 7 ”
因为,如果是后者,就会静态的只能删除 i 为 7 的数据,前者可以 在方法参数中设置传入的参数的值,在 sq 语中,#{id}来接收传进来的 i 值
如果将这里的 void 变为 int,最后测试的时候返回的是这个 sq 语影响的行数
代码测试

    @Testpublic void testDeleteById(){empMapper.deleteById(17);}
 
 
添加
编写 SQ 语句
 
    @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);
 
这里同样将 SQ 语设置为动态的,只不过在方法的形参列表中传递的不是一个个的参数,而是实体类 Emp 的对象 emp,在调用方法的时候,设置并传入 emp 的相应的参数
 
代码测试

    @Testpublic void testInsert(){//构造员工对象Emp emp =new Emp();emp.setUsername("zhang");emp.setName("张章");emp.setImage("1.png");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);}
 
 
添加时返回主键
- 描述:在数据添加成功后,需要获取插入数据库数据的主键。如:添加套餐数据时,还需要维护套餐菜品关系表数据。
 

如果直接输出获取主键,会发现返回的是 Null 而无法获得主键
- 实现:
 

只需要在@insert注解上面加上 options 注即可,这里第一个属性表示主键是 id 字段,第二个属性表示要获取主键
这时候,再添加一次数据,发现可以返回主键了
 
更新
编写 SQ 语句

    @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);
 
 
代码测试

    @Testpublic void testUpdate(){//构造员工对象Emp emp =new Emp();emp.setId(1);emp.setUsername("haenggg");emp.setName("张g11111章");emp.setImage("121.png");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(2000,1,1));emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);//执行更新员工信息操作empMapper.update(emp);}
 
 
查询全部
编写 SQ 语句

 
代码测试

 
根据 id 查询
编写 SQ 语句

 
代码测试

 
出现的问题以及解决

但是后面的几项查询结果都是 Null
解决方案
- 方案一
 

- 方案二
 

- 方案三★★★
 

 
条件查询
编写 SQL 语句

    @Select("select * from emp where name like '%${name}%' and gender = #{gender} and " +"entrydate between #{begin} and #{end} order by update_time desc ")public List<Emp> list(String name, Short gender, LocalDate begin , LocalDate end);
 
 
代码测试


 
xml 映射文件
快速入门

 
将 mapper 接口的注解注释掉,只保留方法
EmpMapper.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">
<mapper namespace="com.example.mapper.EmpMapper"><select id="list" resultType="com.example.pojo.Emp">select * from emp where name like concat('%',#{name},'%') and gender = #{gender} andentrydate between #{begin} and #{end} order by update_time desc</select>
</mapper>
 
运行测试方法也可成功
下载 MybatisX 插件
 
动态SQL
if
随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL。
如果将 test 中的查询条件只设置 name,其他为 null,则无法查询到结果,因为此时是静态的,接口中设置了几个查询条件 test 中就要查询几个条件
这时候可以在 xml 配置文件中编写如下 SQL代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.EmpMapper"><select id="list" resultType="com.example.pojo.Emp">select *from empwhere<if test="name!=null">name like concat('%',#{name},'%')</if><if test="gender!=null">and name like concat('#{gender}')</if><if test="begin!=null and end!=null">and entrydate between #{begin} and #{end}</if>order by update_time desc</select>
</mapper>
 
设置动态 sql
即可查询所有姓名中带有”张“的信息
同理,如果这时候查询条件只有两个也可以
但是,如果这样查询就会报错,因为如果第一个条件为 null,sql 语句就会开头出现 and 而语法错误
这个时候可以使用标签
 
if 案例—动态更新
在之前的更新的时候,有些字段需要更新,有些字段不需要更新,所以写代码的时候只需要写需要进行更新的字段就行了,但是,如果不需要更新的字段不写,就会默认更新为 null
如果要使用动态 SQL,则只需要写想要更新的字段,其他字段不会改变而不会变成 null
使用 xml 配置文件
在接口文件中编写一个 update 方法
会发现报错为没有 xml 映射文件的 sql 代码,这时候鼠标放在红线上,点击
即可在 xml 文件中创建(因为安装了 MybatisX 插件)
将更新 SQL语句更写为如下:
对于这里的标签,如果只更改 username,那么后面的都不会成立,那么,会多一个逗号
会语法错误,使用 set 标签可解决这个问题
即可动态更新
此时如果只想将 id 为 1 的 name 改为 qqqqq
 
foreach


<mapper namespace="com.example.mapper.EmpMapper"><!--批量删除员工 (1,2,3)--><!--collection: 遍历的集合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>
 

 
sql 和 include


相关文章:
Mybatis学习笔记注解/xml映射/动态SQL%%%Mybatis教程
介绍 Mybatis 是一款优秀的持久层框架,用于简化 JDBC 的开发 MyBatis中文网 Mybatis 入门 快速入门 步骤 创建 SpringBoot 工程、数据库表 user、实体类 User引入 Mybatis 相关依赖,配置 Mybatis(数据库连接信息)编写 SQL 语…...
Git纯操作版 项目添加和提交、SSH keys添加、远程仓库控制、冲突解决、IDEA连接使用
Git 文章目录 Git项目简单克隆通用操作添加和提交回滚分支变基分支优选 远程项目推送认证抓取、拉取和冲突解决 IEDA类软件连接 最近学原理学的快头秃了,特此想出点不讲原理的纯操作版,不过还是放个图吧 项目简单克隆 git在本人日常中最重要的功能还是…...
使用OpenSSL生成自签证书
什么是OpenSSL OpenSSL是一个开源的软件库和工具套件,用于安全地处理网络数据传输中的加密、解密、安全套接层(SSL)以及传输层安全(TLS)协议等功能。它广泛应用于网站和互联网服务中,以确保数据传输的安全…...
Spring源码解析——Spring事务是怎么通过AOP实现的?
正文 此篇文章需要有SpringAOP基础,知道AOP底层原理可以更好的理解Spring的事务处理。最全面的Java面试网站 自定义标签 对于Spring中事务功能的代码分析,我们首先从配置文件开始人手,在配置文件中有这样一个配置:<tx:annot…...
机器人革命:脑洞大开的前沿机器人技术!
原创 | 文 BFT机器人 01 由生物启发的多模式移动形态机器人 在一个不断运动的世界中,一种新开发的名为M4(多模式移动形态机器人)的机器人展示了在包括滚动、飞行和行走在内的八种不同运动模式之间切换的能力。这款机器人由加州理工学院自主…...
微信小程序动态海报
参考文献: 微信小程序生成分享海报(附带二维码生成) - 简书 需求背景: 微信小程序固定图片,无法自动链接,分享页面内容 解决方案: 拆分海报内容,由以下几个组成 1、用户图像 …...
手写单例模式
一、单例模式的定义 定义: 确保一个类只有一个实例,并提供该实例的全局访问点。 这样做的好处是:有些实例,全局只需要一个就够了,使用单例模式就可以避免一个全局使用的类,频繁的创建与销毁,耗…...
介绍6种解决电脑找不到vcomp140.dll,无法继续执行代码的方法。
在编程和软件开发领域,我们经常会遇到各种错误和问题。其中,找不到vcomp140.dll文件导致无法继续执行代码是一个非常常见的问题。这个问题可能会影响到软件的正常运行,甚至导致整个项目延期。因此,我们需要找到解决方案来解决这个…...
mysql数据物理迁移
文章目录 一、mysql数据物理迁移1.1 物理迁移 一、mysql数据物理迁移 1.1 物理迁移 速度快,需要停机 进入数据库,查看数据存放位置: select datadir; 一般默认存放在/var/lib/mysql 停机数据库,防止有写入数据 systemctl stop …...
构建图像金字塔:探索 OpenCV 的尺度变换技术
构建图像金字塔:探索 OpenCV 的尺度变换技术 引言什么是图像金字塔?为什么需要图像金字塔?构建高斯金字塔构建拉普拉斯金字塔图像金字塔的应用示例:在不同尺度下检测图像中的边缘 结论 引言 在计算机视觉领域,图像金字…...
ios app开发环境搭建
Xcode是Apple iOS的应用市场app store移动应用的开发工具,支持不同设备、不同应用场景的开发,本文主要描述xcode开发工具开发环境的搭建。 如上所示,在macos中,使用app store安装xcode开发工具 如上所示,在macos中&…...
mysql面试题45:读写分离常见方案、哪些中间件可以实现读写分离
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说你知道的读写分离常见方案 读写分离是一种常见的数据库架构方案,旨在分担数据库的读写压力,提高系统的性能和可扩展性。以下是两种常见的…...
【数字IC设计】DC自动添加门控时钟
简介 数字电路的动态功耗主要是由于寄存器翻转带来的,为了降低芯片内部功耗,门控时钟的方案应运而生。作为低功耗设计的一种方法,门控时钟是指在数据无效时将寄存器的时钟关闭,以此来降低动态功耗。 在下图中,展示了…...
前端开发工具vscode
一、下载安装 https://code.visualstudio.com/ 二、安装插件 三、使用 ①、创建一个空目录 ②、利用vscode工具打开该目录 ③、将该目录设置为工作区 在工作区中添加文件,还可以进行浏览器访问(提前安装了Live Server插件) 为工具…...
网络基础2(1)
HTTP 1.应用层协议2.send和recv单独使用不安全3.URL4.urlencode和urldecode5.HTTP协议格式6.HTTP中的常见请求方法POST&&GET7.HTTP的状态码8.HTTP常见Header 🌟🌟hello,各位读者大大们你们好呀🌟🌟 Ƕ…...
系统文件IO、文件描述符fd、重定向、文件系统、动态库和静态库
目录 C文件接口系统文件I/O系统调用和库函数文件描述符0 & 1 & 2FILE和fd的关系文件描述符的分配规则 重定向重定向的本质输出重定向输入重定向追加重定向 dup2函数 FILE理解文件系统了解磁盘的物理结构逻辑抽象文件系统文件系统的图解和解析通过文件系统来理解ls -al通…...
一、K8S第一步搭建
一、初始化操作 1.1、关闭防火墙 systemctl stop firewalld systemctl disable firewalld关闭交换空间 swapoff -a # 临时 sed -ri s/.*swap.*/#&/ /etc/fstab # 永久重启才能生效 根据规划设置主机名 hostnamectl set-hostname <hostname>映射主机 cat >>…...
pwnable-1-fd
pwn的学习周期确实比较长,需要的前置内容也很多,了解到第一题还算比较简单的,那就先来体验一波~顺带附一波网站链接:👉网站链接 题目 WP 最后一行给出了ssh链接方式,那就先连接一波 第一次连接会有第四行的询问&…...
队列的实现(c语言)
队列也是线性表,也是分为两种的:1、顺序队列 2、链队列 顺序队列 #include <stdio.h> #include <stdlib.h>typedef struct {char *base;int front;int erer;int size; }SqQueue;void initSqQueue(SqQueue *queue,int size){queue->base…...
雷电模拟器上使用第一个frida(五)用python实现逆向分析并模拟登陆
上篇通过hook确定了登录代码的位置,参考雷电模拟器上使用第一个frida(四)第一个HOOK之抓包-CSDN博客 接下来逆向分析一下,并用python实现其功能,并模拟登陆。...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...






