初始JavaEE篇 —— Mybatis-plus 操作数据库

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程程(ಥ_ಥ)-CSDN博客

所属专栏:JavaEE

目录

前言 

Mybatis-plus 快速上手

Mybatis-plus 复杂操作

常用注解

@TableName 

@TableField

@TableId

打印日志

条件构造器

QueryWrapper

UpdateWrapper 

LambdaQueryWrapper、LambdaUpdateWrapper

自定义SQL 


前言 

初始JavaEE篇 —— Mybatis操作数据库(上)-CSDN博客

初始JavaEE篇 —— Mybatis操作数据库(下)-CSDN博客

通过前面的学习,我们已经知道了如何使用 Mybatis 来操作数据库了,相较于 JDBC 来说,Mybatis 的使用更加方便和容易上手,但是与我们今天学习的 Mybatis-plus 来说,Mybatis 操作数据库的方式还是比较繁琐的,因为需要我们自己去写SQL语句来实现具体的操作,而Mybatis-plus对于简单的查询,根本就不需要我们自己写SQL语句了,甚至连XML文件都无需生成了。

Mybatis-plus 快速上手

1、创建项目工程:

File -> New -> Project:

然后选择对应的项目配置:

接着,选择Lombok、MySQL driver依赖即可:

2、在pom文件中,添加Mybatis-plus 所需的依赖,刷新Maven:

SpringBoot 2.x:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.11</version>
</dependency>

SpringBoot 3.x:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.11</version>
</dependency>

3、在yml文件中,添加MySQ数据源配置,以及

# 配置数据库连接
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver

4、编写对应的SQL脚本:

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
USE mybatis_test;-- 创建表[用户表]
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (`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() ON UPDATE now(),PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; -- 添加用户信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

5、编写实体类:

@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;
}

6、编写mapper接口:

@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {}

注意:这里只需要继承 BaseMapper<T> 这个接口即可。

7、编写测试方法:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid testSelectById() {System.out.println(userInfoMapper.selectById(1));}
}

8、运行测试方法,观察结果:

从最终结果来看,查询数据成功了,而我们并没有在mapper接口中去编写任何方法以及去实现,但最终却能成功执行,这就是 Mybatis-plus 的强大之处。

接下来,我们测试其他的方法是否可以成功执行。

插入:

删除:

修改:

以上这些基本的增删改查都是可以使用Mybatis-plus提供的方法。 

学会了如何简单使用Mybatis-plus之后,我们接下来就需要学习更加复杂的操作。

Mybatis-plus 复杂操作

常用注解

@TableName 

首先,我们来想一个问题:Mybatis-plus 是如何知道查询的是哪个表的呢?这就是通过前面继承的BaseMapper<T> 中泛型来决定的。但问题是数据库中的表是 user_info,而实体类却是UserInfo,两者对应的名称是不同的,这怎么找呢?Mybatis-plus 默认通过 驼峰 转 蛇形 的方式,将实体类转换为蛇形字段,从而去对应的数据库中查找,因此,UserInfo 转换后的结果就是 user_info,在数据库中成功找到该表,因此最终执行的操作可以对应上。但问题又来了:在实际开发中,并不是所有的程序员都会遵守 Mybatis-plus 的规定的,万一有人将 UserInfo 写成了 user_info 呢?该怎么办?Mybatis-plus 给我们提供了注解 @TableName,让我们手动指定数据库的表名,继而其会根据表名去对应的数据库中查找,如果找到的话,就会执行相应的操作;反之,则会抛出异常。

使用 @TableName 之前: 

使用 @TableName 之后:

注意:在实际开发中,最好还是按照规范来,避免出现一些不可预测的问题。 

@TableField

既然表名会出现上述情况,同样字段名称也是会出现上述情况的。(Mybatis-plus 也是按照BaseMapper中的泛型实体类的字段名去数据库对应的数据表中查询对应的字段名称)这里是使用 @TableField 注解来指定查找的字段名。

使用 @TableField 之前:

使用 @TableField 之后:

@TableId

当 数据库中主键名称 和 属性名 对应不上,不能使用 @TableField,而应该使用 @TableId。

如果我们在快速上手时, 去仔细观察 插入方法 对应在 数据库中的结果的话,会有一个奇怪的现象:我们并未指定 id 的值,正常来说是在原始的 id 上进行自增的,而数据库中对应的值,更像是一个自增的随机数。

这需要使用 @TableId 中的 type 属性来解决。我们可以 ctrl + 左键 点击 @TableId,去观察:

当我们修改 @TableId 的 type 的值为 Type.AUTO之后,再去插入数据,观察数据库:

注意:表中的数据是默认是按照 id升序 来排列的,而图中最前面两条数据的 id 是要比1小的,因此我们可以猜测出其是负数(可以去赋值id到画图板上看一下),如果有小伙伴遇到的数是正数的话,那么最终自增的值应该是证书的最大值+1,因为如果插入的数比数据库中原始的数据还要小的话,那么一直自增下去,总有一天,会到达该值,这时就会有冲突,因此,自增的值是从最大值开始自增的。

打印日志

为了方便学习与观察SQL语句的执行结果,我们可以配置SQL语句的执行日志。

# 配置 Mybatis-plus 日志
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

该日志和我们前面学习的Mybatis的日志只是最开始的前缀不一致,Mybatis 对应的前缀是 Mybatis,而 Mybatis-plus 对应的前缀是 Mybatis-plus。

条件构造器

前面学习了简单的CRUD,但在实际开发中肯定不止这些场景,还有一些复杂查询等操作,同样Mybatis-plus 也是提供了相应的支持。

MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。

在 MyBatis-Plus 中,Wrapper 类是构建查询和更新条件(这里指的是where子句)的核心工具。以下是主要的 Wrapper 类及其功能:

  • AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。它定义了条件构造的基本逻辑,包括字段(column)、值(value)、操作符(condition)等。所有的 QueryWrapper、UpdateWrapper、LambdaQueryWrapper 和 LambdaUpdateWrapper 都继承自 AbstractWrapper。

  • QueryWrapper:专门用于构造查询条件,支持基本的等于、不等于、大于、小于等各种常见操作。它允许你以链式调用的方式添加多个查询条件,并且可以组合使用 and 和 or 逻辑。

  • UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。与 QueryWrapper 类似,它也支持链式调用和逻辑组合。使用 UpdateWrapper 可以在不创建实体对象的情况下,直接设置更新字段和条件。

  • LambdaQueryWrapper:这是一个基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。这种方式提高了代码的可读性和可维护性,尤其是在字段名可能发生变化的情况下。

  • LambdaUpdateWrapper:类似于 LambdaQueryWrapper,LambdaUpdateWrapper 是基于 Lambda 表达式的更新条件构造器。它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。

接下来就学习具体如何使用:

QueryWrapper

QueryWrapper 并不只用于查询语句,只要是涉及到了where子句的地方,都可以使用,即删除、修改、查询都能使用。

查询:

SQL: 

select id, username, password, age from user_info 
where age = 18 and username like '%admin%';

测试代码:

@Test
void testSelect() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();// 构造SQL语句queryWrapper.select("id", "username", "password", "age").eq("age", 18).like("username", "%admin%");// 执行SQL语句System.out.println(userInfoMapper.selectList(queryWrapper));
}

QueryWrapper的select方法需要传输两个参数,一个是Boolean类型,当其为true时,才会将后面的字段列表加入最终的SQL中,eq方法是equals的简写,用于设置单个字段的相等条件,like方法用于构建模糊查询条件。当SQL语句构建完成之后,最终需要执行,还得通过Mybatis-plus的提供的方法来调用。

注意:select方法、eq方法以及like方法传输的第一个参数都是对应数据库的字段名,而不是实体类的属性名。

更新:

SQL:

update user_info set delete_flag = 1 where age < 20;

测试代码:

@Test
void testUpdate2() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lt("age", 20);UserInfo userInfo = new UserInfo();userInfo.setDeleteFlag(1);userInfoMapper.update(userInfo, queryWrapper);
}

这里的 lt 是 less than 的缩写,用于设置单个字段的小于条件。le 是 less than or equals to 的缩写,用于设置单个字段的小于等于条件。ge 是 greater than or equals to 的缩写,用于设置单个字段的大于等于条件。gt 是 greater than 的缩写,用于设置单个字段的大于条件。ne 是 not equals 的缩写,用于设置单个字段的不相等条件。

删除:

SQL:

delete from user_info where age = 18;

测试代码:

@Test
void testDelete2() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.eq("age", 18);userInfoMapper.delete(queryWrapper);
}

UpdateWrapper 

对于更新操作,可以直接使用 UpdateWrapper,这样不必创建实体类,从而直接设置更新字段和条件。

基础更新:

SQL:

update user_info set delete_flag = 0, age = 5 where id in (1,2,3);

测试代码:

@Test
void testUpdate3() {UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.set("delete_flag", 0).set("age", 5).in("id", List.of(1, 2, 3));userInfoMapper.update(updateWrapper);
}

set 用于设置更新语句中的 SET 字段。通过调用 set 方法,可以指定在更新操作中要修改的字段及其新值。in 用于设置单个字段的 IN 条件,即字段的值在给定的集合中。

基于SQL更新:

update user_info set age = age + 10 where id in (1,2,3);

 测试代码:

@Test
void testUpdate4() {UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.setSql("age = age + 10").in("id", List.of(1, 2, 3));userInfoMapper.update(updateWrapper);
}

setSql 用于设置更新语句中的 SET 部分 SQL 包含 数据库字段。

注意:如果上述传递的列名错误的话,也会发生badsql异常,可以通过打印的SQL语句观察。

LambdaQueryWrapper、LambdaUpdateWrapper

QueryWrapper和UpdateWrapper存在一个问题:需要写死字段名,如果字段名发生变更,可能会
因为测试不到位酿成事故(因为字段名是String类型)。

  • LambdaQueryWrapper:这是一个基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。这种方式提高了代码的可读性和可维护性,尤其是在字段名可能发生变化的情况下。

  • LambdaUpdateWrapper:类似于 LambdaQueryWrapper,LambdaUpdateWrapper 是基于 Lambda 表达式的更新条件构造器。它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。

还是直接来看代码:

@Test
void testSelect() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();// 构造SQL语句queryWrapper.select("id", "username", "password", "age").eq("age", 18).like("username", "%admin%");// 执行SQL语句System.out.println(userInfoMapper.selectList(queryWrapper));
}

上面是使用QueryWrapper来编写的查询,而下面是使用LambdaQueryWrapper编写的查询:

@Test
void testSelect2() {LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.select(UserInfo::getId,UserInfo::getUsername,UserInfo::getPassword,UserInfo::getAge).eq(UserInfo::getAge, 18).like(UserInfo::getUsername, "%admin%");userInfoMapper.selectList(lambdaQueryWrapper);
}

整体上来看对于字段参数都是采用Lambda表达式的写法来通过实体类获得属性,从而根据属性来推出对应字段名。 同样使用下面的方式来创建LambdaQueryWrapper:

@Test
void testSelect3() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();// 通过调用 Lambda 方法成功获取到了 LambdaQueryWrapper对象LambdaQueryWrapper < UserInfo > lambda = queryWrapper.lambda();lambda.select(UserInfo::getId,UserInfo::getUsername,UserInfo::getPassword,UserInfo::getAge).eq(UserInfo::getAge, 18).like(UserInfo::getUsername, "%admin%");userInfoMapper.selectList(queryWrapper);
}

同样LambdaUpdateWrapper的写法也是类似的。

@Test
void testUpdate5() {// 同样可以直接new LambdaUpdateWrapper// 也可以调用UpdateWrapper的lambda方法UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.lambda().set(UserInfo::getDeleteFlag, 0).set(UserInfo::getAge, 10).in(UserInfo::getId, Arrays.asList(1, 2, 3));userInfoMapper.update(updateWrapper);
}

自定义SQL 

在实际开发中,Mybatis-plus提供的操作可能并不满足我们的实际需求,Mybatis-plus也提供了自定义SQL的功能,我们可以利用Wrapper构造查询条件,再结合Mapper编写SQL。

注意:Mybatis-plus支持自定义SQL的版本要 3.0.7 及其以上。

SQL:

select id, username, password, age from user_info where username = 'admin';

 Mapper:

@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {@Select("select id, username, password, age " +"from user_info ${ew.customSqlSegment}")// wrapper 拼接的是 where子句List<UserInfo> selectUserInfo(@Param("ew") Wrapper<UserInfo> wrapper);
//    List<UserInfo> selectUserInfo(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);
}

测试代码:

@Test
void selectUserInfo() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().eq(UserInfo::getUsername, "admin");System.out.println(userInfoMapper.selectUserInfo(queryWrapper));
}

注意: 

1、参数命名:在自定义SQL时,传递的Wrapper对象必须指定参数名为 "ew",且需要通过 @Param 注解来手动绑定参数名为 "ew",否则就会抛异常。

即使我们使用 Constants.WRAPPER 本质是还是绑定参数名为 "ew" 。这里的Constants要用maobidou包下的。

2、在SQL语句中,必须要使用 ${ew.customSqlSegment}来引用Wrapper对象生成的SQL片段。因为 Wrapper 对象生成的SQL片段存储在 customSqlSegment 属性中,因此引用它才能正确提取。

3、 虽然这里使用的是 ${},但是Mybatis-plus 对 Wrapper 条件 做了处理,并不会出现SQL注入的风险。

上述是使用注解的方式来自定义SQL,同样我们也可以使用XML的方式来自定义SQL。 

在yml中配置XML文件的映射路径:

# 配置XML文件的映射路径
# 同样只是前缀发生了变化,从Mybatis变为了Mybatis-plus
mybatis-plus:mapper-locations: classpath:mapper/*.xml

 Mapper:

List<UserInfo> selectUserInfo2(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);

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">
<!-- namespace 表示的该xml文件实现的接口类的全限定名称 -->
<mapper namespace="com.springboot.mybatisplusdemo.mapper.UserInfoMapper"><select id="selectUserInfo2" resultType="com.springboot.mybatisplusdemo.model.UserInfo"><!-- 同样这里只能使用 ${ew.customSqlSegment} -->select * from user_info ${ew.customSqlSegment}</select>
</mapper>

测试代码:

@Test
void selectUserInfo2() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().eq(UserInfo::getUsername, "admin");System.out.println(userInfoMapper.selectUserInfo2(queryWrapper));
}

上述都是简单查询,下面来学习如何编写基于SQL进行更新。

SQL:

update user_info set age = age + 10 where id in (1, 2, 3);

Mapper:

@Update("update user_info set age = #{age} + 10 ${ew.customSqlSegment}")
Integer update(Integer age, @Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);

测试代码:

@Test
void update() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().in(UserInfo::getId, List.of(1, 2, 3));System.out.println("受影响的行数: " + userInfoMapper.update(10, queryWrapper));
}

Wrapper 只是添加了where子句,至于其他部分还是和Mybatis一样去传参和接收参数。

好啦!本期 初始JavaEE篇 —— Mybatis-plus 操作数据库 的学习之旅 就到此结束啦!我们下一期再一起学习吧!

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

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

相关文章

PyQt6实例_批量下载pdf工具_主线程启用线程池

目录 前置&#xff1a; 代码&#xff1a; 视频&#xff1a; 前置&#xff1a; 1 本系列将以 “PyQt6实例_批量下载pdf工具”开头&#xff0c;放在 【PyQt6实例】 专栏 2 本系列涉及到的PyQt6知识点&#xff1a; 线程池&#xff1a;QThreadPool,QRunnable&#xff1b; 信号与…

1.2 斐波那契数列模型:LeetCode 面试题 08.01. 三步问题

动态规划解三步问题&#xff1a;LeetCode 面试题 08.01. 三步问题 1. 题目链接 LeetCode 面试题 08.01. 三步问题 题目要求&#xff1a;小孩上楼梯&#xff0c;每次可以走1、2或3步&#xff0c;计算到达第 n 阶台阶的不同方式数&#xff0c;结果需对 1e9 7 取模。 2. 题目描述…

UE5 学习笔记 FPS游戏制作30 显示击杀信息 水平框 UI模板(预制体)

文章目录 一制作单条死亡信息框水平框的使用创建一个水平框添加子元素调整子元素顺序子元素的布局插槽尺寸填充对齐 制作UI 根据队伍&#xff0c;设置文本的名字和颜色声明变量 将变量设置为构造参数根据队伍&#xff0c;设置文本的名字和颜色在构造事件中&#xff0c;获取玩家…

HTTP---基础知识

天天开心&#xff01;&#xff01;&#xff01; 文章目录 一、HTTP基本概念1. 什么是HTTP&#xff0c;又有什么用&#xff1f;2. 一次HTTP请求的过程3.HTTP的协议头4.POST和GET的区别5. HTTP状态码6.HTTP的优缺点 二、HTTP的版本演进1.各个版本的应用场景2、注意要点 三、HTTP与…

数据结构 KMP 字符串匹配算法

KMP算法是计算机科学中的一种字符串匹配算法&#xff0c;KMP是三个创始人名字首字母 题目 AcWing - 算法基础课 前置知识点 KMP算法是一种高效的字符串匹配算法&#xff0c;算法名称取自于三位共同发明人名字的首字母组合。该算法的主要使用场景就是在字符串&#xff08;也叫…

Conda配置Python环境

1. 安装 Conda 选择发行版&#xff1a; Anaconda&#xff1a;适合需要预装大量科学计算包的用户&#xff08;体积较大&#xff09;。 Miniconda&#xff1a;轻量版&#xff0c;仅包含 Conda 和 Python&#xff08;推荐自行安装所需包&#xff09;。 验证安装&#xff1a; co…

数仓开发那些事(11)

某神州优秀员工&#xff1a;一闪&#xff0c;领导说要给我涨米。 一闪&#xff1a;。。。。&#xff08;着急的团团转&#xff09; 老运维&#xff1a;Oi&#xff0c;两个吊毛&#xff0c;看看你们的hadoop集群&#xff0c;健康度30分&#xff0c;怎么还在抽思谋克&#xff1f…

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案

✅ MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案 前言一、问题现象二、原因分析1. 使用了 strictInsertFill/strictUpdateFill 导致更新失效2. 实体类注解配置错误3. MetaObjectHandler 未生效4. 使用自定义 SQL 导致自动填充失效5. 字段类型不匹配 三、…

C++ STL常用算法之常用算术生成算法

常用算术生成算法 学习目标: 掌握常用的算术生成算法 注意: 算术生成算法属于小型算法&#xff0c;使用时包含的头文件为 #include <numeric> 算法简介: accumulate // 计算容器元素累计总和 fill // 向容器中添加元素 accumulate 功能描述: 计算区间内容器元素…

axios基础入门教程

一、axios 简介 axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;可用于浏览器和 Node.js 环境&#xff0c;支持以下特性&#xff1a; 发送 HTTP 请求&#xff08;GET/POST/PUT/DELETE 等&#xff09; 拦截请求和响应 自动转换 JSON 数据 取消请求 并发请求处理 二…

短视频团队架构工作流程---2025.3.30 李劭卓

短视频团队架构&工作流程—2025.3.30 李劭卓 文章目录 短视频团队架构&工作流程---2025.3.30 李劭卓1 工作职责1.1 编剧&#xff1a;1.2 主编&#xff1a;1.3 总编&#xff1a;1.4 导演&#xff1a;1.5 摄影&#xff1a;1.6 演员&#xff1a;1.7 后期&#xff1a;1.8 美…

MySQL 高效 SQL 使用技巧详解

MySQL 高效 SQL 使用 技巧详解 一、为什么需要优化 SQL&#xff1f; 性能瓶颈&#xff1a;慢查询导致数据库负载升高&#xff0c;响应时间延长。资源浪费&#xff1a;低效 SQL 可能占用大量 CPU、内存和磁盘 I/O。 目标&#xff1a;通过优化 SQL 将查询性能提升 10 倍以上&am…

AI基础03-视频数据采集

上篇文章我们学习了图片的数据采集&#xff0c;今天主要了解一下视频数据采集的方法。视频是由一系列图像构成的&#xff0c;其中每一张图片就是一帧。视频数据采集方法通常有自动图像采集和基于处理器的图像采集两种。我们学习一下如何利用python 工具和笔记本计算机摄像头进行…

Scala 数组

Scala 数组 引言 Scala 作为一门多范式编程语言&#xff0c;融合了面向对象和函数式编程的特点。数组是编程语言中非常基础和常见的数据结构&#xff0c;在 Scala 中也不例外。本文将详细介绍 Scala 中的数组&#xff0c;包括其定义、操作以及在实际开发中的应用。 Scala 数…

Text-to-SQL将自然语言转换为数据库查询语句

有关Text-To-SQL方法&#xff0c;可以查阅我的另一篇文章&#xff0c;Text-to-SQL方法研究 直接与数据库对话-text2sql Text2sql就是把文本转换为sql语言&#xff0c;这段时间公司有这方面的需求&#xff0c;调研了一下市面上text2sql的方法&#xff0c;比如阿里的Chat2DB,麻…

golang 的strconv包常用方法

目录 1. 字符串与整数的转换 2. 字符串与浮点数的转换 3. 布尔值的转换 4. 字符串的转义 5. 补充&#xff1a;rune 类型的使用 方法功能详解 代码示例&#xff1a; 1. 字符串与整数的转换 方法名称功能描述示例Atoi将字符串转换为十进制整数。strconv.Atoi("123&q…

MATLAB详细图文安装教程(附安装包)

前言 MATLAB&#xff08;Matrix Laboratory&#xff09;是由MathWorks公司开发的一款高性能的编程语言和交互式环境&#xff0c;主要用于数值计算、数据分析和算法开发。内置数学函数和工具箱丰富&#xff0c;开发效率高&#xff0c;特别适合矩阵运算和领域特定问题。接下来就…

ShapeCrawler:.NET开发者的PPTX操控魔法

引言 在当今的软件开发领域&#xff0c;随着数据可视化和信息展示需求的不断增长&#xff0c;处理 PPTX 文件的场景日益频繁。无论是自动化生成报告、批量制作演示文稿&#xff0c;还是对现有 PPT 进行内容更新与格式调整&#xff0c;开发者都需要高效的工具来完成这些任务。传…

HTML5贪吃蛇游戏开发经验分享

HTML5贪吃蛇游戏开发经验分享 这里写目录标题 HTML5贪吃蛇游戏开发经验分享项目介绍技术栈核心功能实现1. 游戏初始化2. 蛇的移动控制3. 碰撞检测4. 食物生成 开发心得项目收获后续优化方向结语 项目介绍 在这个项目中&#xff0c;我使用HTML5 Canvas和原生JavaScript实现了一…

有关pip与conda的介绍

Conda vs. Pip vs. Virtualenv 命令对比 任务Conda 命令Pip 命令Virtualenv 命令安装包conda install $PACKAGE_NAMEpip install $PACKAGE_NAMEX更新包conda update --name $ENVIRONMENT_NAME $PACKAGE_NAMEpip install --upgrade $PACKAGE_NAMEX更新包管理器conda update con…