手写Mybatis

news2024/11/24 10:32:44

Mybatis总体流程

(1)加载配置并初始化触发条件:加载配置文件

配置来源于两个地方,一个是配置文件(主配置文件conf. xml, mapper文件*.xml),一个是java代码中的注解,将主配置文件内容解析封装到Configuration,将sql的配置信息加载成为一个mappedstatement对象,存储在内存之中

(2)接收调用请求

触发条件:调用Mybatis提供的API传入参数:为SQL的ID和传入参数对象
处理过程:将请求传递给下层的请求处理层进行处理。

(3)处理操作请求

触发条件:API接口层传递请求过来
传入参数:为SQL的ID和传入参数对象处理过程:

  1. 根据SQL的ID查找对应的MappedStatement对象。
  2. 根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
  3. 获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
  4. 根据MappedStatement对象中的结果映射配置对得到的执行结果进入转换处理,并得到最终的处理结果。
  5. 释放连接资源。

(4)返回处理结果

将最终的处理结果返回。

Mybatis核心构建

核心构建

描述

SqlSession

作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能

Executor

MyBatis执行器,是MyBatis调度的核心,负责SQL语句的生成和查询缓存的维护

StatementHandler

封装了JDBC Statement操作,负责对JDBC statement的操作,如设置参数、将Statement结果集转换成List集合

ParameterHandler

负责对用户传递的参数转换成JDBC Statement所需要的参数

ResultSetHandler

负责将JDBC返回的ResultSet结果集对象转换成List类型的集合

TypeHandler

负责java数据类型和jdbc数据类型之间的映射和转换

MappedStatement

MappedStatement维护了一条<select | update | delete | insert>节点的封装

sqlSource

负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回

BoundSql

表示动态生成的SQL语句以及相应的参数信息

Mybatis层次结构 

代码解析

public class Entry {
    public static void main(String[] args) {
        MtConfiguration configuration = new MtConfiguration("mybatis-config.properties");
        MtSqlSessionFactoryBuilder sqlSessionFactoryBuilder = new MtSqlSessionFactoryBuilder(configuration);
        MtSqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build();
        MtSqlSession sqlSession = sqlSessionFactory.openSession();
        PersonDao personDao = sqlSession.getMapper(PersonDao.class);
        Person person = personDao.queryPersonById(1l);
        System.out.println(person);
    }
}

了解Mybatis使用的同学们,能看出这跟你们常用的Mybatis有什么区别吗?区别还是有的,只是很像有木有。
然后再让大家看看这个仿真版的Mybatis框架由哪些部分组成,下面是框架的代码目录。
在这里插入图片描述

从上面的图中可以看到涵盖了executor、plugin、typehandler等基础组件。然后再看下是如何使用的。

clipboard.png

解析
有些小伙伴可能会有疑问,怎么才能写出这样的框架呢?这个怎么回答呢,其实写出来只需要你对Mybatis的工作原理有大致的了解,知道那些模块是做什么的又是怎么实现的,然后画个流程图,然后定义需要哪些类和接口去实现,最后只需要将这些定义好的类和接口填空就可以了。
那么现在我们来看看这个仿真Mybatis是怎么工作的,当然需要申明的是这个框架仅仅只是作为了解Mybatis运行原理的一个代码练习,有些地方的代码可能只是为了演示这样的效果,并不一定完全跟原生一样。比如Mybatis需要解析XML,而这里我们投了个懒,直接上properties。这样我们就可以重点关注Myabtis的业务流程啦。
接下来对框架的每个部分进行一个简单的说明,具体还请小伙伴去看代码好好了解然后有什么问题直接在评论区或者私信我就可以了,我保证看到就回复,哈哈。

1.configuration模块


顾名思义,就是框架配置类,用于解析配置文件加载相关环境。这里代码里对配置文件的初始化主要有以下这么一个流程。

public MtConfiguration(String configLocation){
    this.configLocation = configLocation;
    init();
}

private void init(){
    try {
        //记载配置文件,这里使用properties代替xml解析
        loadConfigProperties();
        //初始化数据源信息
        initDataSource();
        //解析并加载mapper文件
        loadMapperRegistory();
        //解析加载plugin
        initPluginChain();
        //解析加载typeHandler
        initTypeHandler();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    }
}

可以看到实例类的时候调用init方法进行初始化,分别加载配置信息、初始化数据源信息、解析并加载mapper文件、解析加载plugin、解析加载typeHandler这几个步骤。具体如何进行小伙伴们可以看下代码实现,代码写得简单,相信你们一看就懂。

2.session模块


这个模块用于用户与框架交互的入口。包括常用的sqlSession、sqlSessionFactory以及sqlSessionFactoryBuilder。这几个类完全是仿照Mybatis的,只是类实现会相对简单很多。至于每个类用来干嘛,这个我在之前的文章中有讲述,这里就不多做赘述啦,只是简单引导讲解框架信息。

clipboard.png

3.Mapper映射模块


这个模块主要用来注册我们的mapper映射文件的。

clipboard.png

这里需要说明下MapperData这个类,这个类主要记录sql语句和sql语句返回类型信息的。然后MapperRegistory用来保存方法与MapperData的映射关系,这样我们执行某个方法是就能找到对应的Sql语句和对应的返回类型了。这个过程可以结合Mybatis解析mapper.xml的过程去理解。

public class MapperData {
    private String sql;
    private Class type;
public MapperData(String sql, Class type) {
    this.sql = sql;
    this.type = type;
}

public String getSql() {
    return sql;
}

public void setSql(String sql) {
    this.sql = sql;
}

public Class getType() {
    return type;
}

public void setType(Class type) {
    this.type = type;
}

@Override
public String toString() {
    return "MapperData{" +
            "sql='" + sql + '\'' +
            ", resultType=" + type +
            '}';
}


4.Executor执行模块


这个模块主要用于执行SQL语句并且结合各种handler处理,然后这里只是写了一简单的执行器类。

clipboard.png

5.handler模块


这里模仿Mybatis执行SQL时的过程,stamentHandler用于处理语句集、parameterHandler用于处理参数、resultHandler用于处理结果映射。

clipboard.png

6.plugin模块


这里模仿Myabtis插件的工作原理实现的,也就是说这里和原生Mybatis的plugin基本一样,不过这里我又偷了个懒,目前只能实现对executor的拦截。哈哈,别怪我。

clipboard.png

7.typeHandler模块


这里模仿Mybatis类型处理的机制,用于javaType到jdbcType的映射处理以及jdbcType到javaType的映射处理,当然这只是演示这样的一种效果,具体实现其实没有像Mybatis那样复杂。你们看代码应该也能看出来。

clipboard.png

8.配置模块


这里的对框架的配置使用了简单的properties,主要原因还是简单易懂然后节省时间。

clipboard.png

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

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

相关文章

ReentrantLock源码分析(一)加锁流程分析

一、ReetrantLock的使用示例 static ReentrantLock lock new ReentrantLock(); public static void main(String[] args) throws InterruptedException { new Thread(ClassLayOutTest::reentrantLockDemo, "threadA").start(); Thread.sleep(1000);…

Netty权威指南总结(二)

三、Netty代码相关&#xff1a;(四) EventLoop与EventLoopGroup&#xff1a;Netty的Nio线程是NioEventLoop。1. Reactor线程模型&#xff1a;Reactor模型的三个角色&#xff1a;Reactor&#xff1a;把IO事件分配给对应的Handler处理&#xff0c;功能像是调度器。Acceptor【饿渴…

【C++】C++核心编程(一)---内存四区

C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区 存放函数体的二进制代码&#xff0c;由操作系统进行管理全局区 存放全局变量和静态变量以及常量(字符串常量、全局常量)栈区 由编译器自动分配释放&#xff0c;存放函数的参数值、局部变量等堆区 由程序员分配和释…

jenkins问题

目录 python 不是内部或外部命令&#xff0c;也不是可运行的程序 ‘cmd’ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 git 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 pywintypes.com_error: (-2147024891, ‘拒绝访问。’, None,…

Qt实用技巧:Qt中浮点数的相等比较方式(包括单精度和双精度)

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/129464152 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

Spring——AOP切入点表达式和AOP通知类型

切入点:要进行增强的方法 切入点表达式:要进行增强的方法的描述式 第一种方法的本质是基于接口实现的动态代理(jdk) 第二种是基于cglib实现的动态代理 AOP切入点表达式 而需要加载多个切入点时&#xff0c;不可能每个切入点都写一个切入点表达式 例子 下面的代理描述的是匹配…

条件语句(分支语句)——“Python”

各位CSDN的uu们你们好呀&#xff0c;最近总是感觉特别特别忙&#xff0c;但是却又不知道到底干了些什么&#xff0c;好像啥也没有做&#xff0c;还忙得莫名其妙&#xff0c;言归正传&#xff0c;今天&#xff0c;小雅兰的内容还是Python呀&#xff0c;介绍一些顺序结构的知识点…

Hadoop学习:Yarn

1.YARN介绍 一个通用的资源管理系统和调度平台 YARN不分配磁盘&#xff0c;由HDFS分配 相当于一个分布式的操作系统平台&#xff0c;为上层MR等计算程序提供运算所需要的资源&#xff08;内存、CPU等&#xff09; 2.YARN三大组件 不要忘记AppMaster&#xff0c;他是程序内部…

Android 进程间通信机制(二) mmap 原理

一. 前言 Binder中一次拷贝的实现就是利用mmap(memory mapping)内存映射机制,我们来看看它的工作原理. 二. 参考文章 下面这几篇文章建议先好好阅读一下,都是总结的很好的文章, 每个人理解可能不一样 笔者也是看了好多博客文章和B站视频讲解, 然后加上自己的理解后 输出的一…

程序的编译和链接

程序的编译和链接程序的编译和链接程序的两种环境翻译环境详解编译和链接预处理编译汇编链接运行环境程序的编译和链接 程序的两种环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 …

《数据分析-JiMuReport04》JiMuReport报表设计入门介绍-页面优化

报表设计 2 页面优化 如上图所示的报表&#xff0c;仅仅是展示数据&#xff0c;不过这样看起来似乎太草率了&#xff0c;所以再优化一下吧 保存报表后&#xff0c;在积木报表中就可以看到对应的报表文件 此时我们如果还需要编辑报表&#xff0c;就点击这个报表即可 2.1 居中…

如何设计企业节点的『工业互联网标识解析系统』

一、『星火 链网』体系架构 『星火 链网』以节点形式进行组织互联互通&#xff0c;其中包括三类节点&#xff1a;超级节点、骨干节点、业务节点。 其底层采用“1N”主从链群架构&#xff0c;支持同构和异构区块链接入主链。在全国重点区域部署『星火 链网』超级节点&#…

three.js的demo例子-STL加载对象组件

three.js的demo例子-STL加载对象组件 提示&#xff1a;demo示例中所涉及到的three.js安装插件方法这里就不单个说明了哈&#xff0c;有需要的网上有很多教程 文章目录three.js的demo例子-STL加载对象组件效果展示插件模型一、HTML部分二、script部分1.引入库2.初始化数据3.监听…

卷王都在偷偷准备金三银四了...

年终奖没发&#xff1b; 简历石沉大海&#xff1b; 发消息只读不回 打开某招聘&#xff0c;看了看岗位&#xff0c;这个厂还不错&#xff0c;可是要求好高&#xff0c;我啥都不会。 “哎&#xff0c;算了&#xff0c;我简历还没更新呢&#xff0c;我躺到6月份拿到年终奖再跑…

【动态规划】多重背包问题,分组背包问题

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

名创优品业绩狂飙,手握哪些王牌?

撰稿 | 多客 来源 | 贝多财经 2023年注定是名创优品(NYSE:MNSO、HKEX:9896)发展史上具有重要意义的一年&#xff0c;不仅是创立的10周年&#xff0c;也是全球品牌战略升级的开局之年。 2月28日&#xff0c;名创优品公布了2023财年第二财季未经审计财务报告。得益于全球化战略…

机器学习笔记之狄利克雷过程(六)预测任务求解

机器学习笔记之狄利克雷过程——预测任务求解引言回顾&#xff1a;基于狄利克雷过程的预测过程预测任务的求解过程引言 上一节引出了基于狄利克雷过程的预测任务&#xff0c;本节将对该预测任务进行求解。 回顾&#xff1a;基于狄利克雷过程的预测过程 在已知隐变量样本集合…

Windows 环境安装Scala详情

为了进一步学习Spark&#xff0c;必须先学习Scala 编程语言。首先开始Scala 环境搭建。温馨提示&#xff1a;本文是基于Windows 11 安装Scala 2.13.1 版本第一步&#xff1a;确保本机已经正确安装JDK1.8 环境第二步&#xff1a;Scala 官网下载我们所属scala版本文件。Scala 官网…

JavaScript(WebAPI)

目录 1.什么是Web API? 2.DOM和DOM树 3.获取元素 4.事件 5.操作元素 获取/修改元素内容 1.innerText 2. innerHTML 获取/修改元素属性 获取/修改表单元素属性 获取/修改样式属性 1.修改内联样式 2.修改元素应用的CSS类名 6.操作节点 新增节点 删除节点 7.案例…

Vue3的composition API—setup函数, ref函数,reactive函数

1、Setup 函数 1.setup 是vue3中的一个配置项 2、setup是所有组件所需要的数据和方法都需要配置到setup中的 3、setup两种返回值&#xff1a; 若返回一个对象 若返回一个渲染函数 mian.js文件 注意&#xff1a;尽量不与Vue2混用 setup中无法访问vue2中的配置 不能是async函数…