MyBatis-Plus:告别手写 SQL 的高效之道
目录
1. MyBatis-plus 简介
2. MyBatis-Plus 快速上手
2.1 项目准备
2.2 导入 MyBatis-Plus 依赖
2.3 配置数据库连接
2.4 配置 MyBatis-Plus 日志打印
3. 使用 MyBatis-Plus
3.1 创建 model 类
3.2 创建 mapper 接口
3.3 MyBatis-Plus 映射机制
3.3.1 @TableName & @TableField
3.3.2 @TableId
3.4 CRUD 单元测试
3.4.1 insert
3.4.2 delete
3.4.3 update
3.4.4 select
4. 条件构造器
4.1 主要的条件构造器
4.2 构造器常用方法
4.3 QueryWrapper
4.3.1 查询数据
4.3.2 更新数据
4.3.3 删除数据
4.4 UpdateWrapper
4.5 Lambda 形式构造器
4.5.1 LambdaQueryWrapper
4.5.2 LambdaUpdateWrapper
5. 自定义 SQL
5.1 示例1
5.2 示例2
1. MyBatis-plus 简介
基于之前的学习, 我们可以通过 MyBatis-Generator 自动生成 mapper 层代码, 提升了开发效率.
其实还有一种更加简洁的方式, 根本不需要显示的展示 mapper 接口中的方法, 也不需显示的展示出 xml 操的 SQL 映射, 我们直接就可以调用现有的方法来操作数据库, 那就是 MyBatis-Plus.
MyBatis-Plus(简称 MP) 是⼀个 MyBatis 的增强工具, 在 MyBatis 的基础上只做增强不做改变(MyBatis 有的, MyBatis-Plus 也有), 为简化开发, 提高效率而生.
MyBatis-Plus 🚀 为简化开发而生
2. MyBatis-Plus 快速上手
2.1 项目准备
首先, 需要创建一个 Spring 项目, 创建项目阶段我们只需引入这三个依赖:
2.2 导入 MyBatis-Plus 依赖
项目创建完毕后, 需要我们手动在 pom 文件中导入 MyBatis-Plus 依赖:
<!-- SpringBoot 3.x 版本 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency>
2.3 配置数据库连接
使用 MyBatis-Plus, 当然也需要在 yml 文件中配置数据库连接:
spring:# 配置数据库连接datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: 111111driver-class-name: com.mysql.cj.jdbc.Driver
2.4 配置 MyBatis-Plus 日志打印
为了更方便的观察 SQL 执行结果, 我们也可以像在 MyBatis 时一样, 配置打印 SQL 执行的日志信息:
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # MyBatis-Plus 日志打印
3. 使用 MyBatis-Plus
完成以上配置相关的工作后, 就可以使用 MyBatis-Plus 了.
3.1 创建 model 类
和使用 MyBatis 一样, 我们需要创建一个 Java 类, 和数据库表中的字段相映射:
3.2 创建 mapper 接口
我们仍需创建 mapper 接口, 但在这个接口中, 我们不需定义任何操作数据库的方法, 更不需使用 XML 或注解来定义 SQL, 只需继承 BaseMapper 接口, BaseMapper 接口中定义了 CRUD 方法, 只要我们的 mapper 接口继承了 BaseMapper, 那我们的 mapper 接口就可以使用其中所有的方法:
3.3 MyBatis-Plus 映射机制
上文提到的 BaseMapper 接口是一个泛型接口, 对泛型占位符传入 Java 类, MyBatis-Plus 就会根据 Java 命名规范和数据库命名规范自动匹配到该类对应的数据库表:
当然, MyBatis-Plus 也会根据命名规范, 自动将 Java 属性和数据库表字段相映射(不用像 MyBatis 那样在配置文件中手动设置驼峰转换了).
MyBatis-plus 的自动映射规则如下:
- 表名: Java 类的大驼峰表示法转换为蛇形表示法(下划线分割). UserInfo ==> user_info
- 字段名: Java 属性的小驼峰表示法转换为蛇形表示法(下划线分割). deleteFlag => delete_flag
- 主键: 默认将 Java 类中, 名称为 "id" 的属性, 映射为表中的主键字段
综上, MyBatis-Plus 继承并扩展了 MyBatis, 并提供了一系列增强功能, 包括默认开启的驼峰命名转换和自动匹配数据库表.
3.3.1 @TableName & @TableField
虽然 MyBatis-Plus 会根据 Java 和 数据库的命名规范自动进行类和表以及属性和字段之间的映射, 但是, 规范毕竟只是规范, 再加上程序员的水平参差不齐, 甚至有的都不知道 MyBatis-Plus 这些自动映射的功能, 因此, MyBatis-Plus 也提供了手动指定映射的方式.
使用 @TableName 手动指定该类映射的数据库表, 使用 @TableField 手动指定该属性映射的数据库表字段:
其实, 显式声明胜于隐式推断, 我们在开发中最好也显式声明映射关系, 消除框架猜测的需要, 减少意外行为的可能性.
3.3.2 @TableId
上文说到, MyBatis-plus 会默认将 Java 类中, 名称为 "id" 的属性, 映射为表中的主键字段.
如图所示, 我们调用 BaseMapper 中的 selectById 方法, MyBatis-plus 会默认将类中的 id 属性映射到表中的主键字段, 进行查找:
(但是, 属性名和字段名必须按照规范命名(或者两者名称完全一致), MyBatis-plus 才能推断出映射关系)
但是, 如果我们将属性名和主键字段名都修改为 "user_id", 即使两者的名称仍然是相匹配的, 但是由于 Java 属性的名称不是 "id", MyBatis-plus 也不会将其和表中的主键映射, 报错:
此时, 我们就需要使用 @TableId 注解来显式指定哪个属性是对应数据库表的主键:
此外, 如上图所示. @TableId 还可以将主键属性的值设置为自增类型, 这样在插入数据时, 我们就无需手动设置主键属性(如 userId) 的值, MyBatis-plus 会自动将主键属性的值设置为表中主键自增后的值.
3.4 CRUD 单元测试
3.4.1 insert
由于 mapper 接口继承了 BaseMapper 接口, 因此我们直接调用 BaseMapper 中的 insert 方法进行数据插入即可:
但是, 我们发现了一个问题, 新插入记录的 id 列是一个很大的数值, 并非从 1 开始自增.(id 为主键, 应该是自增的)
这是因为 MyBatis-Plus 只知道 id 字段是主键, 但并不知道 id 也是 auto_increment 自增的.
要解决这个问题, 我们需要使用 @TableId 指定主键, 并设置自增类型:
因为我们现在表中的数据最大的 id 是 24, 因此新插入数据时, id 是从 24 开始往后自增的.
如果想要 id 从 1 开始自增, 那么就需要删除表中 id 比 1 大的记录, 并设置主键进行自增的起始值:
3.4.2 delete
删除记录, 同样直接调用 BaseMapper 提供的方法:
3.4.3 update
更新记录, 同样直接调用 BaseMapper 提供的方法:
3.4.4 select
查询操作, 同样直接调用 BaseMapper 提供的方法:
4. 条件构造器
4.1 主要的条件构造器
上文带大家简单了解了一下 MyBatis-plus 的简单 CRUD 操作, 但是在实际开发中, 我们会用到更复杂的操作, 因此 MyBatis-plus 也为我们提供了支持 --- wrapper 条件构造器.
条件构造器的核心职责就是构建 SELECT, UPDATE 和 DELETE 语句中的 WHERE 条件.(构造查询/条件)
注意: 条件构造器只能用于构造查询条件, 不能构造整个 sql 语句.
主要的条件构造器如下:
-
AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性(所有的 wrapper 类都继承于它)。它定义了条件构造的基本逻辑,包括字段(column)、值(value)、操作符(condition)等。所有的 QueryWrapper、UpdateWrapper、LambdaQueryWrapper 和 LambdaUpdateWrapper 都继承自 AbstractWrapper。
-
QueryWrapper:专门用于构造查询条件,支持基本的等于、不等于、大于、小于等各种常见操作。它允许你以链式调用的方式添加多个查询条件,并且可以组合使用
and
和or
逻辑。 -
UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。与 QueryWrapper 类似,它也支持链式调用和逻辑组合。使用 UpdateWrapper 可以在不创建实体对象的情况下,直接设置更新字段和条件。
-
LambdaQueryWrapper:这是一个基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。这种方式提高了代码的可读性和可维护性,尤其是在字段名可能发生变化的情况下。
-
LambdaUpdateWrapper:类似于 LambdaQueryWrapper,LambdaUpdateWrapper 是基于 Lambda 表达式的更新条件构造器。它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。
以上条件构造器(如 QueryWrapper<T>, LambdaQueryWrapper<T>, UpdateWrapper<T>, LambdaUpdateWrapper<T>, DeleteWrapper<T>, LambdaDeleteWrapper<T>)都是泛型类, MyBatis-Plus 通过传入的泛型 T 来推断出我们要操作的数据库表.
官方文档: 条件构造器 | MyBatis-Plus
4.2 构造器常用方法
以下方法支持链式调用.
4.3 QueryWrapper
QueryWrapper 并不只用于查询语句, 无论是修改, 删除, 查询, 都可以使用 QueryWrapper 来构建查询条件.
注意: 使用 QueryWrapper 的方法时(如 select(), lt(), gt(), eq() 等), 传入字符串应是数据库表中的字段名, 而不是 Java 属性名.
4.3.1 查询数据
QueryWrapper 除了可以使用其父类 AbstractWrapper 提供的方法构造查询条件外, QueryWrapper 还额外实现了 select 方法, 可以手动指定要查询的列.
因此, QueryWrapper 不仅用来构造 select 操作的查询条件 (WHERE 子句), 它还用于指定 select 操作中需要查询的列.
sql 查询语句:
SELECT id, username, password, age FROM user_info WHERE (age = 15 AND username LIKE "%min%");
构造器实现:
@Testvoid selectByQueryWrapper() {// SELECT id, username, password, age FROM user_info WHERE (age = 15 AND username LIKE "%min%")QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();wrapper.select("id, username, password, age").eq("age", 15).like("username", "min");userInfoMapper.selectList(wrapper).forEach(System.out::println);}
4.3.2 更新数据
更新数据, 有以下三种方式:
- 根据 UpdateWrapper 构造器进行更新
- 根据实体类和 QueryWrapper 构造器进行更新
- 根据实体类进行更新
第三种上文已经演示, 第一种下文讲, 这里演示第二种, 数据 QueryWrapper 进行更新.
使用 QueryWrapper 来更新数据, 需要结合实体类使用.
其中, QueryWrapper 用来构造查询条件, 实体类用来构造要更新的内容:
sql 更新语句:
UPDATE user_info SET delete_flag= 1 WHERE (age < 20)
QueryWrapper 实现:
4.3.3 删除数据
sql 删除语句:
DELETE FROM user_info WHERE (age = 5)
QueryWrapper 实现:
@Testvoid deleteByQueryWrapper() {// DELETE FROM user_info WHERE (age = 5)QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();wrapper.eq("age", 5);userInfoMapper.delete(wrapper);}
4.4 UpdateWrapper
UpdateWrapper 除了可以使用父类 AbstractWrapper 提供的方法构造查询条件(where 子句)外, 其还额外实现了如下方法:
- set 方法: 可以指定 UPDATE 操作中要更新的内容(SET 子句).
- setSql 方法: 可以直接设置 SET 子句的 SQL 片段. (可以执行更复杂的更新操作)
与 QueryWrapper 类似, UpdateWrapper 在使用 set(), eq(), lt() 等方法时, 传入的是数据库表中的字段名.
UpdateWrapper 是专门用于 UPDATE 操作的.
上文说到, MyBatis-plus 提供的 update 操作有三种方式:
- 根据 UpdateWrapper 构造器进行更新
- 根据实体类和 QueryWrapper 构造器进行更新
- 根据实体类进行更新
上文已经演示了第 2, 3 种, 这里就使用 UpdateWrapper 演示第一种.
示例 1: UpdateWrapper 使用 set 方法构造更新内容
Sql 更新语句:
UPDATE user_info SET delete_flag= 0 WHERE (age < 20)
构造器实现:
@Testvoid updateByUpdateWrapper() {// UPDATE user_info SET delete_flag= 0 WHERE (age < 20)UpdateWrapper<UserInfo> wrapper = new UpdateWrapper<>();wrapper.set("delete_flag", 0).lt("age", 20);userInfoMapper.update(wrapper);}
示例二: UpdateWrapper 使用 setSql 构造更新内容
sql 更新语句:
UPDATE user_info SET age = age + 10 WHERE (id IN (2,3,4))
构造器实现:
@Testvoid updateByUpdateWrapper3() {// 使用 SQL 进行更新// UPDATE user_info SET age = age + 10 WHERE (id IN (2,3,4))UpdateWrapper<UserInfo> wrapper = new UpdateWrapper<>();wrapper.setSql("age = age + 10").in("id", List.of(2, 3, 4));userInfoMapper.update(wrapper);}
示例三: 使用 in 方法构造查询条件
UPDATE user_info SET delete_flag=1,age=5 WHERE (id IN (2,3,4))
构造器实现:
@Testvoid updateByUpdateWrapper2() {// UPDATE user_info SET delete_flag=1,age=5 WHERE (id IN (2,3,4))UpdateWrapper<UserInfo> wrapper = new UpdateWrapper<>();wrapper.set("delete_flag", 1).set("age", 5).in("id", List.of(2, 3, 4)); // .in("id", Arrays.asList(1, 2, 3));userInfoMapper.update(wrapper);}
4.5 Lambda 形式构造器
使用 QueryWrapper 和 UpdateWrapper 构造查询条件时, 我们使用 eq, set, select, lt 等方法传入表字段名时, 传入的是字符串, 当真实的字段名称发生改变时, 我们就需要手动修改传入的字符串参数, 易发生错误, 因此存在硬编码问题.
使用 Lambda 形式的构造器就可以避免这个错误:
- LambdaQueryWrapper
- LambdaUpdateWrapper
Lambda 构造器, 传入参数时, 不再是字符串, 而是使用 Lambda 表达式来提取出类的属性名.
形如: UserInfo::getId, 该 Lambda 表达式等价于: (UserInfo user) -> user.getId();
含义为: 接受一个 UserInfo 对象, 返回其 id 属性的名称.
因此:
- Lambda 构造器: 使用方法引用 (::) 引用 Java 实体类的 Getter 方法, MyBatis-Plus 内部会提取属性名, 进而推断出对应的表字段.
-
普通构造器: 直接在方法参数中传入数据库表的字段名(字符串形式).
4.5.1 LambdaQueryWrapper
sql 查询语句:
SELECT id, username, password, age FROM user_info WHERE (age = 15 AND username LIKE "%min%")
LambdaQueryWrapper 构造器实现:
@Testvoid selectByLambda() {// SELECT id, username, password, age FROM user_info WHERE (age = 15 AND username LIKE "%min%")LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();wrapper.select(UserInfo::getId, UserInfo::getUsername,UserInfo::getPassword, UserInfo::getAge).eq(UserInfo::getAge, 5).like(UserInfo::getUsername, "min");userInfoMapper.selectList(wrapper).forEach(System.out::println);
4.5.2 LambdaUpdateWrapper
示例一:
sql 更新语句:
UPDATE user_info SET age = age + 10 WHERE (id IN (2,3,4))
LambdaUpdateWrapper 构造器实现:
@Testvoid updateByLambda2() {// 使用 SQL 进行更新// UPDATE user_info SET age = age + 10 WHERE (id IN (2,3,4))LambdaUpdateWrapper<UserInfo> wrapper = new LambdaUpdateWrapper<>();wrapper.setSql("age = age + 10").in(UserInfo::getId, List.of(2, 3, 4));userInfoMapper.update(wrapper);}
示例二:
sql 更新语句:
UPDATE user_info SET delete_flag=1,age=5 WHERE (id IN (2,3,4))
LambdaUpdateWrapper 构造器实现:
@Testvoid updateByLambda() {// UPDATE user_info SET delete_flag=1,age=5 WHERE (id IN (2,3,4))LambdaUpdateWrapper<UserInfo> wrapper = new LambdaUpdateWrapper<>();wrapper.set(UserInfo::getDeleteflag, 1).set(UserInfo::getAge, 5).in(UserInfo::getId, List.of(2, 3, 4));userInfoMapper.update(wrapper);}
5. 自定义 SQL
虽然 MyBatis-Plus 提供的构造器十分强大, 但工作中难免会遇见一些构造器实现不了 SQL, 因此 MyBatis-Plus 也提供了自定义 SQL 功能, 即结合 Wrapper(构造 where 查询条件)和 注解/xml 编写更复杂的 SQL.
上文说到, MyBatis-Plus 在 MyBatis 的基础上, 只做增强, 不做改变, 因此 MyBatis 的注解和 xml 功能, 在 MyBatis-Plus 上依旧可以使用. 并且在 MyBatis-plus 上使用注解和 xml 的方式与 MyBatis 完全一致.
唯一不同的是, MyBatis-plus 使用 xml 时, 配置文件需要稍作改变:
mybatis-plus:mapper-locations: "classpath*:/mapper/**.xml" # Mapper.xml
以下是使用自定义 SQL 的几个注意事项:
- 参数命名: 在自定义 SQL 时, 传递 Wrapper 对象作为参数时, 必须使用注解@Param(Constants.WRAPPER) 将 Wrapper 对象重命名为 ew.(即使参数名本来就是 ew, 也需要添加 @Param)
- 使用 ${ew.customSqlSegment}: 在 SQL 语句中, 使用 ${ew.customSqlSegment} 来引用Wrapper 对象生成的 SQL 片段.
- 需要在 注解/xml 中, 手动编写完整的 SQL 语句, 手动引入 Wrapper 对象或其他自定义参数.
- 使用 MyBatis-plus 提供的自定义 sql 功能, Mybatis-plus 版本需不低于3.0.7
5.1 示例1
SQL 语句:
select * from user_info WHERE (age = ?)
使用 Wrapper + 注解, 自定义 sql:
5.2 示例2
sql 语句:
update user_info set age = age + 1 WHERE (id IN (2,3,4))
使用 Wrapper + 注解, 自定义 sql:
上述示例使用的是注解来自定义 sql 的, 使用 xml 也可以, 并且格式和注解一样.
END
相关文章:
MyBatis-Plus:告别手写 SQL 的高效之道
目录 1. MyBatis-plus 简介 2. MyBatis-Plus 快速上手 2.1 项目准备 2.2 导入 MyBatis-Plus 依赖 2.3 配置数据库连接 2.4 配置 MyBatis-Plus 日志打印 3. 使用 MyBatis-Plus 3.1 创建 model 类 3.2 创建 mapper 接口 3.3 MyBatis-Plus 映射机制 3.3.1 TableName &a…...
【AI News | 20250320】每日AI进展
AI Repos 1、servers 该仓库提供详细入门指南,用户可通过简单步骤连接Claude客户端,快速使用所有服务器功能。此项目由Anthropic管理,展示MCP的多样性与扩展性,助力开发者为大语言模型提供安全、可控的工具与数据访问。 2、awe…...
让“树和二叉树”埋在记忆土壤中--性质和概念
Nice to meet your! 目录 树的介绍: 树的创建: 二叉树的概念和结构: 二叉树的存储结构: 树的介绍: 概念和结构: 不知你们是否在现实中看见过分为两个叉的枯树,大概长这样: 那…...
210、【图论】课程表(Python)
题目 思路 这道题本质上是一个拓扑排序。每次先统计每个点的入度个数、然后再统计点与点之间的邻接关系,找到入度为0的点作为起始遍历点。之后每遍历到这个点之后,就把这个点后续的邻接关系边的点入度减去一。当某个点入度为0时,继续被加入其…...
【Linux篇】进程控制
📌 个人主页: 孙同学_ 🔧 文章专栏:Liunx 💡 关注我,分享经验,助你少走弯路! 1. 进程创建 1.1 fork函数 在linux中fork函数是非常重要的函数,它从已存在进程中创建一个…...
freeswitch(在呼叫失败的情况下如何播放语⾳提⽰)
亲测版本centos 7.9系统–》 freeswitch1.10.9 本人freeswitch安装路径(根据自己的路径进入) /usr/local/freeswitch/etc/freeswitch⼀般我们在打电话时会听到『您拨的电话正在通话中,请稍后再 拨.』,或『电话⽆应答』之类的提⽰,我们在 FreeSWITCH ⾥也可以这样做。 …...
软考系统架构设计师之计算机组成与体系结构笔记
一、计算机硬件组成 1. 冯诺依曼结构与哈佛结构 冯诺依曼结构:以存储器为中心,指令和数据统一存储,通过总线连接运算器、控制器、输入输出设备。其核心思想是“存储程序控制”,但存在存储器访问瓶颈问题。哈佛结构:指…...
gonet开源游戏服务器环境配置
1.mysql搭建 搜索mysql-server apt安装包名 sudo apt search mysql-server 安装mysql-server sudo apt-get install mysql-server 安装完成后会,启动mysql服务及创建系统服务 查看服务状态 systemctl status mysql.service 使用超级权限登陆mysql sudo mysql 授…...
软件工程之软件验证计划Software Verification Plan
个人主页:云纳星辰怀自在 座右铭:“所谓坚持,就是觉得还有希望!” 本文为基于ISO26262软件验证计划模板,仅供参考。 软件验证计划,包括: 1. 软件需求验证计划 2. 软件架构设计验证计划 3. 软件单…...
大模型详细配置
Transformer结构 目前主力大模型都是基于Transformer的,以下是Transformer的具体架构 它由编码器(Encoder)以及解码器(Decoder)组成,前者主要负责对输入数据进行理解,将每个输入 词元都编码成一个上下文语义相关的表示向量;后者…...
Web爬虫利器FireCrawl:全方位助力AI训练与高效数据抓取
Web爬虫利器FireCrawl:全方位助力AI训练与高效数据抓取 一、FireCrawl 项目简介二、主要功能三、FireCrawl应用场景1. 大语言模型训练2. 检索增强生成(RAG):3. 数据驱动的开发项目4. SEO 与内容优化5. 在线服务与工具集成 四、安装…...
产业观察:ASML2025.3.21
一.发展历程 1.1 创业背景 在半导体行业的快速发展背景下,ASML的创业故事拉开了帷幕。1983年, 飞利浦S&I技术总监Georg de Kruyff 与 ASM创始人Arthur del Prado 重启合作讨论,为ASML的创立奠定了基础。双方迅速达成协议,计…...
go语言学习教程推荐,零基础到做项目
一、基础入门阶段 官方教程(免费) • A Tour of Go:交互式入门教程,边学边练 • Go by Example:通过300代码片段学习语法 入门书籍 • 📘《Go语言圣经》中文版(免费在线阅读)&#…...
设计模式 二、创建型设计模式
GoF是 “Gang of Four”(四人帮)的简称,它们是指4位著名的计算机科学家:Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides。他们合作编写了一本非常著名的关于设计模式的书籍《Design Patterns: Elements of Reusable…...
51c大模型~合集73
我自己的原文哦~ https://blog.51cto.com/whaosoft/12318419 #Emu3 视频、图像、文本,只需基于下一个Token预测:智源Emu3发布,验证多模态模型新范式 OpenAI 前首席科学家、联合创始人 Ilya Sutskever 曾在多个场合表达观点࿱…...
【el-upload】el-upload组件 - list-type=“picture“ 时,文件预览展示优化
目录 问题图el-upload预览组件 PicturePreview效果展示 问题图 el-upload <el-uploadref"upload"multipledragaction"#":auto-upload"false":file-list"fileList"name"files":accept".png,.jpg,.jpeg,.JGP,.JPEG,.…...
STM32F103系列配置中断向量表偏移(Keil/STM32CubeIDE)
需要在flash中添加bootloader的话,需要对flash进行分区,即bootloader区和app区(程序运行区),主要记录在 Keil 平台和 STM32CubeIDE平台 上的中断向量表偏移配置,以偏移 0x2800 为例,即预留10k大小的空间给bootloader …...
Redis常用数据类型和使用常见以及基本操作举例(适合初学者,以医药连锁管理系统为背景)
Redis的常见数据类型,包括String、Hash、List、Set、Zset等,这些数据类型都有各自的特点和适用场景。接下来,将这些数据类型与医药连锁管理系统的业务场景进行匹配。 String类型,适合存储单个值。在医药连锁管理系统中࿰…...
ASL扩展坞方案|Type-c转换器方案|ASL原厂代理商
安格瑞科技代理的ASL主板组件系列包括CS5211、CS5311、CS5232、CS5263、CS621x、CS5523、CS5518等产品; CS5228ANDP to HDMI(4K60HZ)CS5262ANDP (4lanes) to HDMI2.0 4k60Hz VGACS5263ANDP(4lanes) to HDMI2.0 4k60HzCS5363ANDP (4lanes) to HDMI2.0 4k60Hz CS521…...
论文略读(2025.3.18-更新中)
关于可控视频生成 I2V3D: Controllable image-to-video generation with 3D guidance Image to Video工作,能够实现给一张图,输出一个视频,且可以控制相机。动态信息来自于用户手工设计(相机移动,人体骨骼驱动&#x…...
基于SpringBoot的“校园招聘网站”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“校园招聘网站”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统整体功能图 局部E-R图 系统首页界面 系统注册…...
【Linux进程七】程序地址空间
【Linux进程七】程序地址空间 1.进程的地址空间分布2.类型的本质是偏移量3.什么是进程地址空间4.页表的映射和访问权限字段5.地址空间的作用 1.进程的地址空间分布 堆是向上扩展的,栈是向下扩展的 因为字符常量区和代码区相邻,受到同样的保护,…...
Linux C/C++编程——线程
线程是允许应用程序并发执行多个任务的一种机制,线程参与系统调度。 系统调度的最小单元是线程、而并非进程。 线程包含在进程之中,是进程中的实际运行单位。一个线程指的是进程中一个单一顺序的控制流(或者说是执行路线、执行流)…...
【Spring Boot 中 `@Value` 注解的使用】
文章目录 一、前言二、Value 注解简介三、Value 注解的常见用法1. 读取 application.properties 或 application.yml 配置值(1)配置文件示例(2)Java 代码示例(3)测试输出 2. 使用 Value 设置默认值3. 读取系…...
【CAD二次开发】调试无法进入断点提示无可用源问题(非空心断点)
问题截图:显示无可用源,关闭后F5走完后,启动的调试就中断了 操作是:打开Cad,打开dwg后,执行命令,就出现以上截图问题。 问题来源:通常是由于 AutoCAD 的 纤程模式(Fiber&…...
Ubuntu下Docker部署Misskey:打造你的去中心化社交平台
引言 在信息爆炸的时代,人们对于社交平台的需求日益增长,同时也更加注重数据的隐私和自由。Misskey作为一个开源的去中心化社交平台,为用户提供了一个全新的选择。本文将详细介绍如何在Ubuntu Linux环境下,利用Docker快速部署Mis…...
【Vue3】01-vue3的基础 + ref reactive
首先确保已经有了ES6的基础 本文介绍 vue 的基础使用以及 两种响应数据的方式。 目录 1. 创建一个vue应用程序 2. Vue模块化开发 3. ref 和 reactive 的区别 1. 创建一个vue应用程序 所需的两个文件: https://unpkg.com/vue3/dist/vue.global.js https://un…...
C++实现rabbitmq生产者消费者
RabbitMQ是一个开源的消息队列系统,它实现了高级消息队列协议(AMQP), 特点 可靠性:通过持久化、镜像队列等机制保证消息不丢失,确保消息可靠传递。灵活的路由:提供多种路由方式,如…...
Simple-BEV的bilinear_sample 作为view_transformer的解析,核心是3D-2D关联点生成
文件路径models/view_transformers 父类 是class BiLinearSample(nn.Module)基于https://github.com/aharley/simple_bev。 函数解析 函数bev_coord_to_feature_coord的功能 将鸟瞰图3D坐标通过多相机(针孔/鱼眼)内外参投影到图像特征平面࿰…...
Rust嵌入式开发环境搭建指南(基于Stm32+Vscode)
Rust嵌入式开发环境搭建指南(基于Stm32+Vscode) 部分目录如下所示: 目录 简介Rust开发环境安装STM32开发工具链安装VSCode环境配置VSCode插件安装调试器配置项目创建与配置常见问题与解决方案简介 本文档旨在指导开发者如何搭建基于Rust语言的STM32嵌入式开发环境。相比传…...
springboot操作redis集群,注意事项
整合redis可查看博文 springboot 整合redis_springboot整合redis csdn-CSDN博客 集群中操作注意事项 1 多键操作失败: 当使用multiGet等需要同时访问多个键的方法时,如果没有使用Hash Tags,这些键可能会被分配到不同的槽中。如果这些槽位于…...
计算机技术系列博客——目录页(持续更新)
1.1 博客目录专栏 1.1.1 博客文章导航 计算机技术系列博客——目录页 1.1.2 网页资源整理 2.1 计算机科学理论 2.2 软件工程技术 2.2.1.1 编程语言 Java Java语言基础 (1) Java基础知识总结01——Java基础篇 (2) Java基础知识总结02——集合框架篇 (3) Java基础知识总结03—…...
@maptalks/gl-layers中的VectorTileLayer的setStyle属性的全部line配置
maptalks/gl-layers中的VectorTileLayer的setStyle属性的全部line配置 关于 maptalks/gl-layers 中 VectorTileLayer 的 setStyle 方法 在 maptalks/gl-layers 库中,VectorTileLayer 提供了一个灵活的方式来设置矢量瓦片图层的样式。通过调用 setStyle 方法…...
sql小记,20250319
ps:基于sqlserver 一、绩效管理系统表设计 1.表设计 Users用户表:包含id,用户名,密码。 AppraisalBases评价(职位基数)表:包含职位id,职位年终奖基数 AppraisalCoeffcients评价系数表:包含类别id, 类别&…...
【亚马逊云科技】大模型选型实战(挑选和测评对比最适合业务的大模型)
文章目录 前言1、实验内容2、手册内容 一、环境准备二、Prompt 实战与模型配置2.1 基于 Amazon Bedrock 对比测试不同模型的逻辑推理效果2.2 基于 Amazon Bedrock 对比测试不同模型知识问答能力2.3 Prompt 实战结果分析 三、基于 Amazon Bedrock Evaluations 进行模型评测与自动…...
Linux 用户与组管理实战:经验分享与最佳实践
在 Linux 系统管理中,用户和组的管理是保障系统安全和资源分配的重要环节。本文将深入介绍如何创建和管理用户与组,包括 UID、GID 的设置,主组与附加组的分配,以及常见问题的排查和解决。本文还结合实际操作经验,总结了…...
详解如何通过Python的BeautifulSoup爬虫+NLP标签提取+Dijkstra规划路径和KMeans聚类分析帮助用户规划旅行路线
系统模块: 数据采集模块(爬虫):负责从目标网站抓取地点数据(如名称、经纬度、描述等) 数据预处理模块(标签算法):对抓取到的地点数据进行清洗和分类。根据地点特征&…...
Java Stream两种list判断字符串是否存在方案
这里写自定义目录标题 背景初始化方法一、filter过滤方法二、anyMatch匹配 背景 在项目开发中,经常遇到筛选list中是否包含某个子字符串,有多种方式,本篇主要介绍stream流的filter和anyMatch两种方案,记录下来,方便备…...
C语言-指针变量和变量指针
指针 预备知识 内存地址 字节:字节是内存的容量单位,英文名Byte,1Byte8bits 地址:系统为了便于区分每一个字节面对它们的逐一进行编号(编号是唯一的),称为内存地址,简称地址。int…...
CMS漏洞-WordPress篇
一.姿势一:后台修改模板拿WebShell 1.使用以下命令开启docker cd /www/wwwroot / vulhub / wordpress / pwnscriptum docker - compose up - d 如果发现不能开启,可以检查版本和端口 2.访问网址登录成功后 外观 👉编辑 👉404.…...
初识Brainstorm(matlab)
Brainstorm是一款开源应用程序,专门用于分析脑部记录数据:MEG、EEG、fNIRS、ECoG、深部电极等。该应用程序免费,而且不需要Matlab许可证。Brainstorm主要优势是简单直观的图形界面,不需要任何编程知识。具体内容,可查看…...
2025年智能系统、自动化与控制国际学术会议(ISAC 2025)
重要信息 2025 International Conference on Intelligent Systems, Automation and Control 2025年3月28-30日 | 中国西安理工大学 | 会议官网: www.icisac.org 简介 在国家大力推动高质量发展与创新驱动战略的背景下,智能制造与自动化控制行业正迎…...
GGUF、Transformer、AWQ 详解与关系梳理
GGUF、Transformer、AWQ 详解与关系梳理 一、核心概念解析 Transformer 定义 :2017 年 Google 提出的基于自注意力机制的神经网络架构,是大语言模型的通用基础架构。功能 :用于文本生成、翻译、问答等任务,如 BERT、GPT 系列、…...
学习笔记|arduino uno r3|DS1307时钟芯片|Atmega328P| 设置时间|读取时间|无源晶振:DS1307时钟芯片实验
目录 芯片pinout: 实验器件: 实验连线 解决AVR 架构不支持 printf() 方法 使用GetTimeAndDate.ino设置时间: 使用SetTimeAndDate.ino设置时间: 芯片pinout: DS1307 是美国 DALLAS 公司推出的 I 总线接口实时时钟芯…...
Linux--进程创建
进程创建 写时拷贝(时间换空间) 更新页表项权限为只读----子进程写入----触发系统错误系统缺页中断,系统开始检测,系统判断写入区域是数据区还是代码区,如果是代码区就终结进程,如果是数据区就进行写时拷贝…...
MySQL 创建用户,建库,建表
以下是在 MySQL 中创建用户、数据库、表的详细操作步骤: 一、登录 MySQL -- 使用 root 用户登录(需替换为实际密码) mysql -u root -p输入密码后回车,进入 MySQL 命令行界面。 二、创建数据库 -- 创建名为 test_db 的数据库&a…...
成都国际数字影像产业园,文创产业运营新典范深度解析
成都国际数字影像产业园位于成都市蓉北商圈金牛片区福堤路99号,是金牛区政府与树莓集团携手打造的省级“文化科技”融合示范园区。该产业园已成为西南地区乃至全国数字影像产业的一颗璀璨明珠,其成功运营模式堪称文创产业运营的新典范。 产业定位与资源…...
33、如果 std::vector 的元素是指针,需要注意什么?
对 std::vector 元素为指针的情况,需要注意以下几点: 内存管理: 如果 std::vector 存储的是原始指针,那么仅仅清空 vector 或者让 vector 被销毁,并不会释放指针所指向的内存。因此,需要确保在 vector 被销…...
Docker 速通(总结)
Docker 命令 镜像 docker build: 从 Dockerfile 构建镜像。docker pull: 从 Docker Hub 或其他注册表拉取镜像。docker push: 将镜像推送到 Docker Hub 或其他注册表。docker images: 列出本地镜像。docker rmi: 删除本地镜像。 容器 docker run: 创建并启动一个新的容器。…...
算法训练篇06--力扣611.有效三角形的个数
目录 1.题目链接:611.有效三角形的个数 2.题目描述: 3.解法一:(暴力解法)(会超时): 4.解法二(排序双指针) 1.题目链接:611.有效三角形的个数 2.题目描述: 给定一个包含非负整数的数组 nums …...