MyBatis

手写MyBatis流程

架构流程图

封装数据

封装到Configuration中

1、封装全局配置文件,包含数据库连接信息和mappers信息

2、封装*mapper.xml映射文件

封装操作:Builder类

Builder类用来操作配置文件(全局配置文件和mapper映射文件),将配置数据封装到类中。

XmlConfigBuilder

提供parse方法将dataSource信息封装到Configuration

XmlMapperBuilder

提供parse方法将mapper.xml信息封装到Configuration

XmlStatementBuilder

提供parse方法封装MappedStatement信息(此处应用了创建者模式)

XmlScriptBuilder

提供parse方法封装SqlNode信息

数据封装类:

Configuration

封装DataSource和MappedStatement

注意:在Configuration中还提供了创建四大组件的功能!!!

DataSource

封装了连接数据库所需的四大属性:数据库驱动、url、username、passwrod

MappedStatement

每一个CRUD标签都对应一个MappedStatement,其中包含了标签类型(StatementType)、参数类型(ParameterType)、结果类型(ResultType)、Sql文本包装类(SqlSource)

SqlSource

此接口只是对SqlNode做了一些包装,并提供getBound方法,用来获取sql文本和参数列表

1、StaticSqlSource

包含已经解析过的sql文本和参数信息(名称和类型)列表

2、RawSqlSource

用来封装只包含#{}的SqlNode

在其构造方法中,实现了以下操作:

(1)调用SlqNode的apply方法,拼接sql文本

(2)将#{}替换成?

(3)生成StaticSqlSource

在其getBound方法中,实现了以下操作:

将构造参数中生成的StaticSqlSource转化成BoundSql

2、DynamicSqlSource

用来封装包含${}的SqlNode,在getBound方法中,实现了以下操作:

(1)调用SlqNode的apply方法,拼接sql文本

(2)将#{}替换成?

(3)生成BoundSql

注意:因为含有${},解析时需要替换成参数值,所以每次传入不同的参数,都需要调用此方法,重新生成可执行的sql。

SqlNode

不同的SqlNode实现封装了不同类型的Sql文本,并提供了apply方法,用来将sql文本拼接到全局变量DynamicContext中

遍历mapper.xml文件,将不同的Node封装到不同的SqlNode实现类中。

1、StaticSqlNode

用来封装只包含#{}的sql文本。

2、TextSqlNode

用来封装包含${}的sql文本。并在其apply方法中解析了${},将${}替换成相应的参数值。

3、IfSqlNode

用来封装If标签的sql文本。

4、MixSqlNode

用来封装SqlNode集合。并在其apply方法中遍历了集合,并调用了每个元素的apply方法。(此处用到了组合模式)

如下mapper.xml文件对应的SqlNode:

mapper.xml映射文件:

对应生成的MixedSqlNode:

BoundSql

封装JDBC可执行的sql文本和参数信息(参数名、参数类型)列表

执行JDBC

SqlSession

提供CRUD方法,用户可以直接调用。

DefaultSqlSession
SqlSessionFactory

SqlSession工厂

DefaultSqlSessionFactory
SqlSessionFactoryBuilder(构建者模式)

用configuration创建SqlSession????

JDBC四大组件

Executor

执行器,执行JDBC。其中涉及一级缓存和二级缓存。

BaseExecutor

实现了Executor接口,提供query方法,如果存在一级缓存,那么返回一级缓存的数据;如果不存在一级缓存,则从数据库查询

SimpleExecutor(应用了里氏替换原则)

继承了BaseExecutor,忽略了二级缓存的存在,直接从数据库查询数据。

CachingExecutor

继承了BaseExecutor,如果存在二级缓存,使用二级缓存,否则从数据库查询。

statementHandler(此处应用了策略模式)

创建statement对象,比如PreparedStatementHandler,执行JDBC操作。

ParameterHandler

参数处理器,将参数信息添加到statement中

ResultHandler

对结果ResultSet进行处理,转化成List

设计模式整理

组合模式

因为xml中的sql文本是以层级标签的形式组成的,所以通过递归调用生成了SqlNode树。

模板模式

工厂模式

构建者模式

代理模式

杂项

MyBatis分页插件

MyBatis常见面试题

手写MyBatis流程的更多相关文章

  1. 手写mybatis框架笔记

    MyBatis 手写MyBatis流程 架构流程图 封装数据 封装到Configuration中 1.封装全局配置文件,包含数据库连接信息和mappers信息 2.封装*mapper.xml映射文件 ...

  2. 要想精通Mybatis?从手写Mybatis框架开始吧!

    1.Mybatis组成 动态SQL Config配置 Mapper配置 2.核心源码分析 Configuration源码解析 SqlSessionFactory源码解析 SqlSession源码解析 ...

  3. 手写MyBatis ORM框架实践

    一.实现手写Mybatis三个难点 1.接口既然不能被实例化?那么我们是怎么实现能够调用的? 2.参数如何和sql绑定 3.返回结果 下面是Mybatis接口 二.Demo实现 1.创建Maven工程 ...

  4. 手写mybatis框架-增加缓存&事务功能

    前言 在学习mybatis源码之余,自己完成了一个简单的ORM框架.已完成基本SQL的执行和对象关系映射.本周在此基础上,又加入了缓存和事务功能.所有代码都没有copy,如果也对此感兴趣,请赏个Sta ...

  5. 带码农《手写Mybatis》进度3:实现映射器的注册和使用

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!

  6. 《手写Mybatis》第4章:Mapper XML的解析和注册使用

    作者:小傅哥 系列:https://bugstack.cn/md/spring/develop-mybatis/2022-03-20-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%B ...

  7. Mybatis执行流程学习之手写mybatis雏形

    Mybatis是目前开发中最常用的一款基于ORM思想的半自动持久层框架,平时我们都仅仅停留在使用阶段,对mybatis是怎样运行的并不清楚,今天抽空找到一些资料自学了一波,自己写了一个mybatis的 ...

  8. 从零搭建Spring Boot脚手架(4):手写Mybatis通用Mapper

    1. 前言 今天继续搭建我们的kono Spring Boot脚手架,上一文把国内最流行的ORM框架Mybatis也集成了进去.但是很多时候我们希望有一些开箱即用的通用Mapper来简化我们的开发.我 ...

  9. 手写Mybatis和Spring整合简单版示例窥探Spring的强大扩展能力

    Spring 扩展点 **本人博客网站 **IT小神 www.itxiaoshen.com 官网地址****:https://spring.io/projects/spring-framework T ...

随机推荐

  1. 题解 SP1716 【GSS3 - Can you answer these queries III】

    \[ Preface \] 没有 Preface. \[ Description \] 维护一个长度为 \(n\) 的数列 \(A\) ,需要支持以下操作: 0 x y 将 \(A_x\) 改为 \( ...

  2. 工业狗转行AI的心路历程

    2020年2月16日,晴 昨晚下了一场雪,大概是晚上八九点的样子,细碎的雪花在无风的夜里直嗖嗖的往下掉,门前的轿车顶上覆了薄薄的一层.路灯下的小巷格外的寂静,裹着我的睡衣在昏黄的灯光下站了许久,冠状病 ...

  3. MongoDB -> kafka 高性能实时同步(采集)mongodb数据到kafka解决方案

    写这篇博客的目的 让更多的人了解 阿里开源的MongoShake可以很好满足mongodb到kafka高性能高可用实时同步需求(项目地址:https://github.com/alibaba/Mong ...

  4. CentOS使用Postfix发送邮件

    1)配置hosts映射 [root@mail ~]# ifconfig ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mt ...

  5. 命令拼接符 || && 区别

    &&   前面的命令执行成功,执行拼接符后面的命令. ||      前面的命令执行失败,执行拼接符后面的命令. 举例: (1)whoami && net user 真 ...

  6. C#实现读取IPv6 UDP Socket数据,再发送出去

    C#实现读取IPv6 UDP Socket数据,再发送出去. 不知为何,黑框点一下就停止刷新了,再点一下,就继续刷新了. using System; using System.Collections. ...

  7. 7个有用的JS技巧

    就如其他的编程语言一样,JavaScript也具有许多技巧来完成简单和困难的任务. 一些技巧已广为人知,而有一些技巧也会让你耳目一新. 让我们来看看今天可以开始使用的七个JavaScript技巧吧! ...

  8. [WPF 自定义控件]在MenuItem上使用RadioButton

    1. 需求 上图这种包含多选(CheckBox)和单选(RadioButton)的菜单十分常见,可是在WPF中只提供了多选的MenuItem.顺便一提,要使MenuItem可以多选,只需要将MenuI ...

  9. .NET面试题整理(持续更新)

    1.已知值类型保存在线程栈中,引用类型保存在堆中 struct Point{ public int x,y; } public sealed class program{ public static ...

  10. css中伪类和伪元素

    伪类和伪元素时对那些我们不能通过class.id等选择元素的补充 伪类的操作对象是文档树中已有的元素(可以给已有元素加了一个类替代),而伪元素则创建了一个文档数外的元素(可以添加一个新元素替代) CS ...