First Project:)being confused and embrassed… luckily no one is staring at you but willing to help,as long as you try to find and explain a bug,try debugging、、
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
|| Name | Age | City | |----|----------|-----|------------| |0| Alice |25| Niu York |-- 行索引(0, 1, 2, 3)标识每一行的位置 |1| Bob |30| Los Angeles|-- 列索引(Name, Age, City)表示不同的数据字段 |2| Carol |28| Chicago |-- 每一列(Name, Age, City)都包含相应的数据 |3| David |22| Houston |-- 每一列都是一个 Pandas Series,包含相同类型的数据
<!-- 定义查询 --> <selectid="selectUser"resultType="User"> SELECT * FROM users WHERE id = #{id} </select> <!-- 映射结果到对象 --> <resultMapid="BaseResultMap"type="User"> <idcolumn="id"property="id"/> <resultcolumn="username"property="username"/> <resultcolumn="password"property="password"/> </resultMap>
1.2 注解方式
1 2
@Select("SELECT * FROM users WHERE id = #{id}") User selectUser(int id);
核心功能:
动态 SQL:MyBatis 允许你在 XML 中编写动态 SQL 语句,可以根据条件动态构建 SQL 查询。
1 2 3 4 5 6 7 8 9 10
<selectid="selectUsers"parameterType="map"resultType="User"> SELECT * FROM users WHERE 1=1 <iftest="username != null"> AND username = #{username} </if> <iftest="password != null"> AND password = #{password} </if> </select>
参数传递:MyBatis 支持多种参数传递方式,包括单个参数、多个参数、Map 和注解等。
1 2
@Select("SELECT * FROM users WHERE id = #{id} AND username = #{username}") User selectUserByIdAndUsername(@Param("id")int id, @Param("username") String username);
批处理:MyBatis 允许执行批处理操作,可以有效地执行一组 SQL 语句。
1 2 3 4 5 6 7 8
SqlSessionsqlSession= sqlSessionFactory.openSession(ExecutorType.BATCH); UserMapperuserMapper= sqlSession.getMapper(UserMapper.class); for (User user : userList) { userMapper.insertUser(user); } sqlSession.flushStatements(); sqlSession.commit(); sqlSession.close();
DO(Data Object):通常表示数据库中的数据实体,对应数据库表的结构。它主要用于数据存储和数据库操作,包含与数据库表字段一一对应的属性。类中通常包含与数据库表字段对应的成员变量、getter 和 setter 方法。它不应包含业务逻辑,主要负责数据的持久化和映射。 尽管 PO 和 DO 在一些情况下用法相似,但它们的侧重点有所不同。PO 更侧重于与数据库的交互,强调持久化和数据表映射;而 DO 侧重于在不同层之间传递数据,强调业务逻辑层面的数据封装。
BO(Business Object):通常表示业务层的业务实体,主要用于封装业务逻辑。BO 类一般包含与业务逻辑相关的属性和方法,与具体的数据存储形式无关。包含了一些业务逻辑的操作,比如计算、验证等。它不应直接与数据库进行交互,而是通过调用 Service 层或 DAO 层的方法实现数据的获取和存储。
SELECTdistinct id FROM users; LIMIT 2, 3; ORDERBY col1 DESC, col2 ASC; WHERE col isNULL; -- 子查询:只能返回一个字段的数据,可以将子查询的结果作为 WHRER 语句的过滤条件,配合 (not )in SELECT*FROM mytable1 WHERE col1 IN (SELECT col2 FROM mytable2); -- 分组:将数据按照一个或多个列的值分成不同的组,常与聚合函数(如 SUM、COUNT、AVG 等)一起以对每个组聚合操作 -- GROUP BY 子句: 用于指定按哪些列进行分组; HAVING 子句: 用于对分组后的数据进行筛选。 -- WHERE 过滤行,HAVING 过滤分组,行过滤应当先于分组过滤。 SELECT col, COUNT(*) AS num FROM mytable WHERE col >2 GROUPBY col HAVING num >=2 ORDERBYSUM(column2) DESC;
SELECT:查询出属性,用 AS 给列名、计算字段和表名取别名,以简化 SQL 语句以及连接相同表; select 中 sql 函数计算出的值作为查询出的属性(select round(count()/3, 2) from ..) select 中可以加一个select 用于属性计算(select id, count()/(select count(*) from Users) per from ..) 若有重复列,使用 DISTINCT 去除重复值
LIMIT:LIMIT 2, 3 返回第 3 ~ 5 行。配合排序实现获取最大/最小值。。
WHERE:过滤行,AND 和 OR 用于连接多个过滤条件。优先处理 AND,使用 () 决定优先级; is 搭配 null,IN 操作符用于匹配一组值,其后也可以接一个 SELECT 子句,从而匹配子查询得到的一组值。
ORDER:可以按多个列进行排序,并指定不同的排序方式,默认升序ASC, 降序DESC
GROUP BY 可以放在 WHERE 前、后,想清楚在分组前、后过滤
子查询的结果需要指定别名。
连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
-- 连接(内连接):返回多个表中匹配条件满足的行,不匹配的行不会被包括在结果集中。 -- 使用 (INNER )JOIN 关键字,条件语句使用 ON 而不是 WHERE,连接可以替换子查询且效率一般会更快。 SELECT A.value, B.value FROM tablea AS A JOIN tableb AS B ON A.key = B.key; -- 自连接:可以看成内连接的一种,只是连接的表是自身而已。 SELECT e1.name FROM employee AS e1 INNERJOIN employee AS e2 ON e1.department = e2.department AND e2.name = "Jim"; -- 自然连接:自然连接是把同名列通过等值测试连接起来的,同名列可以有多个。 -- 内连接和自然连接的区别: 内连接提供连接的列,而自然连接自动连接所有同名列。 SELECT A.value, B.value FROM tablea AS A NATURALJOIN tableb AS B; -- 外连接:保留了没有关联的那些行。分为左,右外连接以及全外连接。 -- 左连接返回左表的所有行以及与右表匹配的行。如果右表中没有匹配的行,将会返回 NULL 值。 -- on 后等于新连接出了一张表,where 在新表上进行查询 select Employee.name, Bonus.bonus from Employee leftjoin Bonus on Employee.empId = Bonus.empId where Bonus.bonus <1000or Bonus.bonus isnull
SQL 函数
数学函数:SUM():计算指定列的总和。 AVG():计算指定列的平均值。 MAX():找出指定列的最大值。 MIN():找出指定列的最小值。 COUNT():计算指定列的行数。 ROUND(x,y):把 x 四舍五入到 y 位小数。 ABS():返回绝对值。
B+Tree 索引:是大多数 MySQL 存储引擎的默认索引类型。因为不再需要进行全表扫描,只需要对树进行搜索即可,因此查找速度快很多。除了用于查找,还可以用于排序和分组。 InnoDB 的 B+Tree 索引分为主索引和辅助索引。主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主索引中进行查找。
全文索引:MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。查找条件使用 MATCH AGAINST,而不是普通的 WHERE。全文索引一般使用倒排索引实现,它记录着关键词到其所在文档的映射。InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
索引的优点:大大减少了服务器需要扫描的数据行数。帮助服务器避免进行排序和分组,也就不需要创建临时表(B+Tree 索引是有序的,可以用于 ORDER BY 和 GROUP BY 操作。临时表主要是在排序和分组过程中创建,因为不需要排序和分组,也就不需要创建临时表)。将随机 I/O 变为顺序 I/O(B+Tree 索引是有序的,也就将相邻的数据都存储在一起)。
是大多数 MySQL 存储引擎的默认索引类型因为不再需要进行全表扫描,只需要对树进行搜索即可,因此查找速度快很多。除了用于查找,还可以用于排序和分组可以指定多个列作为索引列,多个索引列共同组成键. 适用于全键值、键值范围和键前缀查找,其中键前缀查找只适用于最左前缀查找。如果不是按照索引列的顺序进行查找,则无法使用索引。 InnoDB 的 B+Tree 索引分为主索引和辅助索引. 主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。
索引优化
1.独立的列 在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引。例如下面的查询不能使用 actor id 列的索引: 2.多列索引 在需要使用多个列作为条件进行查询时,使用多列索引比使用多个单列索引性能更好。例如下面的语句中,最好把 actor id和 film id 设置为多列索引。 3.索引列的顺序 4.前缀索引对于 BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引,只索引开始的部分字符。对于前缀长度的选取需要根据索引选择性来确定。 5.覆盖索引
在系统和 MySQL 进行交互之前,MySQL 驱动会帮我们建立好连接,然后我们只需要发送 SQL 语句就可以执行 CRUD 了。 java 系统在通过 MySQL 驱动和 MySQL 数据库连接的时候是基于 TCP/IP 协议的,多线程请求的时候频繁的创建和销毁连接显然是不合理的。在访问 MySQL 数据库的时候,建立的连接并不是每次请求都会去创建的,而是从数据库连接池中去获取,这样就解决了因为反复的创建和销毁连接而带来的性能损耗问题了。MySQL 的架构体系中也已经提供了这样的一个池子,也是数据库连池。双方都是通过数据库连接池来管理各个连接的,这样一方面线程之前不需要是争抢连接,更重要的是不需要反复的创建的销毁连接。
网络连接必须由线程来处理
网络中的连接都是由线程来处理的,所谓网络连接说白了就是一次请求,每次请求都会有相应的线程去处理的。也就是说对于 SQL 语句的请求在 MySQL 中是由一个个的线程去处理的。 SQL 接口:MySQL 中处理请求的线程在获取到请求以后获取 SQL 语句去交给 SQL 接口去处理。 查询解析器:会将 SQL 接口传递过来的 SQL 语句进行解析,翻译成 MySQL 自己能认识的语言 MySQL 查询优化器:查询优化器内部具体怎么实现的我们不需要是关心,我需要知道的是 MySQL 会帮我去使用他自己认为的最好的方式去优化这条 SQL 语句,并生成一条条的执行计划,比如你创建了多个索引,MySQL 会依据成本最小原则来选择使用对应的索引,这里的成本主要包括两个方面, IO 成本和 CPU 成本。MySQL 优化器 会计算 「IO 成本 + CPU」 成本最小的那个索引来执行 存储引擎:查询优化器会调用存储引擎的接口,去执行 SQL,也就是说真正执行 SQL 的动作是在存储引擎中完成的。数据是被存放在内存或者是磁盘中的(存储引擎是一个非常重要的组件,后面会详细介绍) 执行器:执行器是一个非常重要的组件,因为前面那些组件的操作最终必须通过执行器去调用存储引擎接口才能被执行。执行器最终最根据一系列的执行计划去调用存储引擎的接口去完成 SQL 的执行
存储引擎
当我们系统发出这样的查询去交给 MySQL 的时候,MySQL 会按照我们上面介绍的一系列的流程最终通过执行器调用存储引擎去执行,流程图就是上面那个。 在执行这个 SQL 的时候 SQL 语句对应的数据要么是在内存中,要么是在磁盘中,如果直接在磁盘中操作,那这样的随机IO读写的速度肯定让人无法接受的,所以每次在执行 SQL 的时候都会将其数据加载到内存中,这块内存就是 InnoDB 中一个非常重要的组件:缓冲池 Buffer Pool
关于Buffer Pool、Redo Log Buffer 和undo log、redo log、bin log 概念以及关系: Buffer Pool 是 MySQL 的一个非常重要的组件,因为针对数据库的增删改操作都是在 Buffer Pool 中完成的 Undo log 记录的是数据操作前的样子 redo log 记录的是数据被操作后的样子(redo log 是 Innodb 存储引擎特有) bin log 记录的是整个操作记录(这个对于主从复制具有非常重要的意义) 、、,, ,。
从准备更新一条数据到事务的提交的流程描述
首先执行器根据 MySQL 的执行计划来查询数据,先是从缓存池中查询数据,如果没有就会去数据库中查询,如果查询到了就将其放到缓存池中
Linux 是一种免费、开源的类Unix操作系统内核。它最初由芬兰的Linus Torvalds在1991年创建,并迅速发展成为一个庞大且活跃的开源社区项目。Linux内核是操作系统的核心部分,但通常与 GNU 工具和其他软件一起使用,形成完整的(GNU/Linux)操作系统,通常被称为 Linux发行版(如 Ubuntu、Red Hat、CentOS)
GNU
GNU 计划,译为革奴计划,它的目标是创建一套完全自由的操作系统,称为 GNU,其内容软件完全以 GPL 方式发布。其中 GPL 全称为 GNU 通用公共许可协议,包含了以下内容: 1、以任何目的运行此程序的自由;2、再复制的自由;3、改进此程序,并公开发布改进的自由。
而在 Windows 系统上,PowerShell 是一个更现代、功能更强大的命令行工具,特别适用于系统管理和自动化任务。尽管命令行程序cmd 仍然存在并且仍然可以使用,但PowerShell已成为Windows系统管理和开发的首选工具。
WSL
WSL(Windows Subsystem for Linux)允许用户直接在 Windows 上运行Linux 环境(包括大多数命令行工具、实用程序和应用程序),无需修改,无需单独的虚拟机或双重启动。与完整虚拟机相比,WSL 需要的资源(CPU、内存和存储)更少。 WSL是 Windows10/11 自带的一个功能,默认是关闭的,旨在为希望同时使用 Windows 和 Linux 的用户提供无缝且高效的体验。能够在 Bash shell 中运行Linux,并选择您的发行版(Ubuntu、Debian、OpenSUSE、Kali、Alpine 等)。
开启 Hype-V:ctrl+r - control - 程序 - 开启Windows功能 - 勾选Hype-V
更新wsl版本;或手动下载最新版本的 Linux 内核更新包,运行(双击运行 - 系统将提示您提供提升的权限,选择“是”以安装)
1
wsl --update
将 WSL 2 设置为默认版本
1
wsl --set-default-version 2
安装Linux发行版,创建账号用户密码,Installation successful
1
wsl --install -d Ubuntu
至此,已成功安装并设置了一个与 Windows 操作系统完全集成的 Linux 发行版!下次,您可以以管理员身份打开 PowerShell 或 cmd 命令控制台,输入 wsl 命令即可打开安装好的Linux发行版(如Ubuntu)了。 注意:在wsl中,本地磁盘都位于 /mnt 目录。比如 c 盘位于 /mnt/c 。要进入 d 盘,执行命令 cd /mnt/d