1. 什么是 Mybatis

https://www.bilibili.com/video/BV1MT4y1k7wZ/?spm_id_from=..search-card.all.click&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

1.1. 是什么

image.png

1.2. 解决的问题

%%
▶6.🏡⭐️◼️【🌈费曼无敌🌈⭐️第一步⭐️】◼️⭐️-point-20230419-1501%%
❕ ^f9rguv

image.png
image.png

2. 组成架构

%%
▶7.🏡⭐️◼️【🌈费曼无敌🌈⭐️第一步⭐️】◼️⭐️-point-20230419-1502%%
❕ ^coqkl4

https://github.com/zzyandzzy/mybatis-book/tree/%E4%B8%80%E7%BA%A7%E7%BC%93%E5%AD%98%E8%A3%85%E9%A5%B0%E8%80%85

image.png

image-removebg-preview.png

2.1. 重要组件

  1. 简单执行器
    simpleExecutor,每次执行 SQL 都要预编译 SQL 语句
  2. 可重用执行器
    ReuseExecutor,同一 SQL 语句执行只需要预编译一次 SQL 语句
  3. 批处理执行器
    BatchExecutor,只针对修改操作的 SQL 语句预编译一次,并且需要手动刷新 SQL 执行才生效。
  4. 执行器抽象类
    BaseExecutor,执行上面 3 个执行器的重复操作,比如一级缓存、doQuery、doUpdate 方法。
  5. 二级缓存
    CachingExecutor,与一级缓存的区别:一级缓存查询数据库操作后会直接缓存,二级缓存需要当次数据库操作提交事务后才能进行缓存 (二级缓存跨线程处理,一级缓存不用)。

2.2. 继承关系

image.png

image.png

3. 工作原理

3.1. API

image.png

3.2. 架构设计

%%
▶3.🏡⭐️◼️【🌈费曼无敌🌈⭐️第一步⭐️】◼️⭐️-point-20230419-1458%%
❕ ^p2twgg

image.png

mybatis 架构四层作用是什么呢?

  1. Api 接口层:提供 API 增加、删除、修改、查询等接口,通过 API 接口对数据库进行操作。
  2. 数据处理层:主要负责 SQL 的 查询、解析、执行以及结果映射的处理,主要作用解析 sql 根据调用请求完成一次数据库操作.
  3. 框架支撑层:负责通用基础服务支撑,包含事务管理、连接池管理、缓存管理等共用组件的封装,为上层提供基础服务支撑.
  4. 引导层:引导层是配置和启动 MyBatis 配置信息的方式

3.3. 主要组件及其调用关系

image.png
组件介绍:

  • SqlSession:是 Mybatis 对外暴露的核心 API,提供了对数据库的 CRUD 操作接口。
  • Executor:执行器,由 SqlSession 调用,负责数据库操作以及 Mybatis 两级缓存的维护
  • StatementHandler:封装了 JDBC Statement 操作,负责对 Statement 的操作,例如 PrepareStatement 参数的设置以及结果集的处理。
  • ParameterHandler:是 StatementHandler 内部一个组件,主要负责对 ParameterStatement 参数的设置
  • ResultSetHandler:也是 StatementHandler 内部一个组件,主要负责对 ResultSet 结果集的处理,封装成目标对象返回
  • TypeHandler:用于 Java 类型与 JDBC 类型之间的数据转换,ParameterHandler 和 ResultSetHandler 会分别使用到它的类型转换功能
  • MappedStatement:是对 Mapper 配置文件或 Mapper 接口方法上通过注解申明 SQL 的封装
  • Configuration:Mybatis 所有配置都统一由 Configuration 进行管理,内部由具体对象分别管理各自的小功能模块

3.4. 执行逻辑⭐️🔴

image.png

  1. 读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。
  2. 加载映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

Mybatis 将所有 Xml 配置信息都封装到 All-In-One 重量级对象 Configuration 内部。在 Xml 映射文件中, <parameterMap> 标签会被解析为 ParameterMap 对象,其每个子元素会被解析为 ParameterMapping 对象。 <resultMap> 标签会被解析为 ResultMap 对象,其每个子元素会被解析为 ResultMapping 对象。每一个 <select> 、 <insert> 、 <update> 、 <delete> 标签均会被
解析为 MappedStatement 对象,标签内的 sql 会被解析为 BoundSql 对象。

  1. 构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。
  2. 创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。
  3. Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。
  4. MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。
  5. 输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。
  6. 输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

4. 缓存机制⭐️🔴

%%
▶10.🏡⭐️◼️【🌈费曼无敌🌈⭐️第一步⭐️】◼️⭐️-point-20230319-1948%%
❕ ^rfip5l
image.png

4.1. 一级缓存 - 默认开启

image.png

https://www.bilibili.com/video/BV1VP4y1c7j7/?p=56&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

4.1.1. 一级缓存失效情况

image.png
image.png

4.1.2. key-boundSql

https://blog.csdn.net/key_768/article/details/105855925

image.png

image-20210922085021374

4.1.3. cachekey

https://www.bilibili.com/video/BV1R14y1W7yS?t=731.3&p=29

image.png

image.png

image.png

image.png

4.2. 二级缓存 - 默认关闭

image.png

必须在 SqlSession 关闭或提交之后才有效

二级缓存是 SqlSessionFactory 级别,通过同一个 SqlSessionFactory 创建的 SqlSession 查询的结果会被缓存; 此后若再次执行相同的查询语句,结果就会从缓存中获取

4.2.1. 设计模式-【装饰器+责任链】

image.png

image.png

4.2.2. 二级缓存开启的条件

  1. 在核心配置文件中,设置全局配置属性 cacheEnabled=”true”,默认为 true,不需要设置
  2. 在映射文件中设置标签
  3. 二级缓存必须在 SqlSession 关闭或提交之后有效
  4. 查询的数据所转换的实体类类型必须实现序列化的接口

4.2.3. 二级缓存失效的情况

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
image.png

image.png

4.3. 缓存查询顺序⭐️🔴

  1. 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
  2. 如果二级缓存没有命中,再查询一级缓存
  3. 如果一级缓存也没有命中,则查询数据库
  4. SqlSession 关闭之后,一级缓存中的数据会写入二级缓存

4.4. 整合第三方缓存

只是替换二级缓存,一级缓存是无法替换的

image.png

https://www.bilibili.com/video/BV1u64y1z7k5?p=8

image-20210922084529550

4.5. 不建议使用的原因

https://www.cnblogs.com/yerikm/p/10784339.html

5. Mybatis-plus

MybatisPlus 全套教程入门到精通看这个视频就可以了

https://www.bilibili.com/video/BV1gy4y1778k?p=7

image.png

5.1. SQL 注入原理

https://www.bilibili.com/video/BV19i4y137JK?p=26&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

5.1.1. ISqlInjector-AbstractSqlInjector

image.png

5.1.2. inspectInject

在 AbstractSqlInjector 中,主要是由 inspectInject() 方法进行注入的,如下:

image.png

5.1.3. injectMappedStatement

inspectInject 方法实现中

1
2
methodList.forEach(m -> m.inject(builderAssistant, mapperClass,
modelClass, tableInfo));

最终调用抽象方法 injectMappedStatement 进行真正的注入:

image.png

查看该方法的实现:
image.png

5.1.4. addMappedStatement

以 SelectById 为例查看:
image.png
image.png

可以看到,生成了 SqlSource 对象,再将 SQL 通过 addSelectMappedStatement 方法添加到 meppedStatements 中。最终调用公共方法 addMappedStatement 合成 SQL。

6. 主键策略

https://www.cnblogs.com/zimug/archive/2020/07/23/13364279.html

6.1. 全局唯一 id

https://www.cnblogs.com/jiangxinlingdu/p/8440413.html

7. 雪花算法

雪花算法是由 Twitter 公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。

7.1. 核心思想

长度共 64bit(一个 long 型)

1bit 符号位标识,由于 long 基本类型在 Java 中是带符号的,最高位是符号位,正数是 0,负数是 1,所以 id 一般是正数,最高位是 0。
**41bit 时间截 (毫秒级)**,存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于 69.73 年。
10bit 作为机器的 ID(5 个 bit 是数据中心,5 个 bit 的机器 ID,可以部署在 1024 个节点)。
12bit 作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。

image.png

7.2. 优点

整体上按照时间自增排序,并且整个分布式系统内不会产生 ID 碰撞,并且效率较高。Twitter 测试的峰值是 10 万个每秒。另外,美团公司开源了一个全局唯一 id 生成系统 leaf,它里面也用到了雪花算法去构建全局唯一 id 并且在高性能和高可用方面,做了很多的优化,为美团内部业务提供了每天上亿次的调用。

8. 多租户原理

%%
▶1.🏡⭐️◼️【🌈费曼无敌🌈⭐️第一步⭐️】◼️⭐️-point-20230420-0745%%
❕ ^a77gfv

  1. web 部分修改:

a.在用户登录时,在线程变量(ThreadLocal)中记录租户的 id
b.修改 jdbc 的实现 :在提交 sql 时,从 ThreadLocal 中获取租户 id,  添加 sql 注释,把租户的 schema 放到 注释中。例如:/*!mycat :  schema = test_01 */ sql ;

  2. 在 db 前面建立 proxy 层,代理所有 web 过来的数据库请求。proxy 层是用 mycat 实现的,web 提交的 sql 过来时在注释中指定 schema, proxy 层根据指定的 schema 转发 sql 请求。

https://www.bilibili.com/video/BV1ia4y1K7s1/?spm_id_from=..search-card.all.click&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

https://www.bilibili.com/video/BV1Ve4y1g7Bk/?spm_id_from=..search-card.all.click&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

9. 防 SQL 注入原理⭐️🔴

当我们说“预编译”的时候,其实这个功能来自于数据库的支持,它的原理是先编译带有占位符的 SQL 模板,然后再传入参数让数据库自动替换 SQL 中占位符并执行。在这个过程中,由于预编译好的 SQL 模板本身语法已经定死,因此后续所有参数都会被视为不可执行的非 SQL 片段被转义,因此能够防止 SQL 注入。
八股文常提到的“Mybatis 的 #{} 相比 ${} 可以防止 SQL 注入”这一点,本质上是因为 #{} 占位符会被解析为 SQL 模板中的 ? 占位符,而 ${} 占位符会被直接解析为 SQL 模板的一部分导致的。

https://www.cnblogs.com/Createsequence/p/16963891.html

10. 面试题

[[MyBatis面试题 37道.pdf]]

10.1. Mybatis 是如何进行分页的?分页插件的原理是什么?

11. 插件原理

11.1. 插件机制

  1. 插件机制:
    Mybatis 通过插件 (Interceptor) 可以做到拦截四大对象相关方法的执行,根据需求,完 成相关数据的动态改变。

Executor
StatementHandler
ParameterHandler
ResultSetHandler

  1. 插件原理
    四大对象的每个对象在创建时,都会执行 interceptorChain.pluginAll(),会经过每个插件对象的 plugin() 方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行四大对象的方法需要经过代理.

image.png

11.2. 如何编写插件

Mybatis 仅 可 以 编 写 针 对 ParameterHandler 、 ResultSetHandler 、 StatementHandler、Executor 这 4 种接口的插件,Mybatis 使用 JDK 的动态代理, 为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象 的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke() 方法,当 然,只会拦截那些你指定需要拦截的方法。实现 Mybatis 的 Interceptor 接口并复写 intercept() 方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可, 记住,还需要在配置文件中配置你编写的插件。

11.3. 分页插件

12. Mapper 代理开发

12.1. 使用方法

image.png

12.2. 注解原理⭐️🔴

Spring-6、整合Mybatis-@MapperScan

12.3. idea 新增目录

不能使用 . 分割,要用 / 分割,否则不会分层

image.png

13. 实战经验

14. 参考与感谢

14.1. Mybatis

14.1.1. 博学谷⭐️✅

14.1.1.1. 视频 - 源码

https://www.bilibili.com/video/BV1R14y1W7yS?p=18&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

14.1.1.2. 资料

1
/Users/taylor/Nutstore Files/Obsidian_data/pages/002-schdule/001-Arch/001-Subject/002-框架源码专题/003-Mybatis/《源码系列-主流框架&中间件》-博学谷-MyBatis资料

14.1.2. 尚硅谷⭐️✅

14.1.2.1. 视频 - 原理 + 演示

https://www.bilibili.com/video/BV1VP4y1c7j7/?p=56&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

14.1.2.2. 资料

1
/Users/taylor/Nutstore Files/Obsidian_data/pages/002-schdule/001-Arch/001-Subject/002-框架源码专题/003-Mybatis/【尚硅谷】MyBatis零基础入门教程

14.1.3. 鲁班大叔

14.1.3.1. 视频 - 源码

https://www.bilibili.com/video/BV1Tp4y1X7FM?p=1&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

14.1.4. 黑马

14.1.4.1. 视频 - 实战

https://www.bilibili.com/video/BV1MT4y1k7wZ/?spm_id_from=..search-card.all.click&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

14.1.4.2. 资料

1
/Users/taylor/Nutstore Files/Obsidian_data/pages/002-schdule/001-Arch/001-Subject/002-框架源码专题/003-Mybatis/黑马mybatis教程全套视频教程-2天Mybatis框架从入门到精通

14.2. Mybatis-Plus

14.2.1. 尚硅谷

14.2.1.1. 视频 - 原理

https://www.bilibili.com/video/BV1Wb411V71s?p=30&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

14.2.1.2. 资料

1
/Users/taylor/Nutstore Files/Obsidian_data/pages/002-schdule/001-Arch/001-Subject/002-框架源码专题/003-Mybatis/MyBatisPlus-尚硅谷

14.2.2. 黑马

14.2.2.1. 视频 - 实战

https://www.bilibili.com/video/BV1oK4y177YN/?spm_id_from=..search-card.all.click&vd_source=c5b2d0d7bc377c0c35dbc251d95cf204

14.2.2.2. 资料

1
/Users/taylor/Nutstore Files/Obsidian_data/pages/002-schdule/001-Arch/001-Subject/002-框架源码专题/003-Mybatis/资料-全面学习Mybatis插件之Mybatis-Plus