【Mybatis】我抄袭了Mybatis,手写一套MyMybatis框架:初窥mybatis源码

2024-01-18 11:36

本文主要是介绍【Mybatis】我抄袭了Mybatis,手写一套MyMybatis框架:初窥mybatis源码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在历经之前几章课程的深入学习之后,我想我们已经初步掌握了如何运用jdbc连接数据库的技术;同时,我们也实现了利用mybatis框架的能力,甚至尝试着手编写、实现了ORM的框架。我坚信大家对MyBatis的理解和应用已经达到了一定程度。然而,你们是否有思考过为何MyBatis能够具备如此强大的效能呢?因此,在本次课程中,我们将全面剖析MyBatis的源代码,以此揭示其背后隐藏着的卓越功能的实现原理。为了方便我们的Debug实验,我们仍然会参考并使用在上一章节课程所提到的Mybatis-Demo模块进行操作。

文章目录

    • 第一行(获取xml配置文件)
    • 第二行(解析xml文件内容)
    • 第三行(构建DefaultSqlSession对象)
    • 第四行(开始执行查询方法)

在接下来的探究过程中,我们首要需要的就是MyBatis的源代码。建议各位同学可以登录mybatis官方网站获取并下载该源代码(地址为:https://github.com/mybatis/mybatis-3)。

在这里插入图片描述

我们首先可以看到我们的启动类是这样的

package com.masiyi;import com.masiyi.dao.UserDao;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;
import java.io.InputStream;/*** @Author masiyi* @Date ${DATE}* @PackageName:com.masiyi* @ClassName: ${NAME}* @Description: TODO* @Version 1.0*/
public class Main {public static void main(String[] args) throws IOException {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);try (SqlSession session = sqlSessionFactory.openSession()) {UserDao mapper = session.getMapper(UserDao.class);mapper.findById(1).forEach(System.out::println);System.out.println("----------------------------");mapper.findAll().forEach(System.out::println);}}
}

第一行(获取xml配置文件)

就和上一篇文章一样。第一行的意思就是引入我们的mybatis的配置文件。这个配置文件要在我们的resource资源目录下面。我们现在去看这个resource类做了哪些动作?

在这里插入图片描述

经过这个方法之后,我们可以看到他需要调类加载器的getResourceAsStream这个方法。

在这里插入图片描述

最终把我们的传进来这个字符串给转化为url。

在这里插入图片描述

实际上他根据我们的类加载器找到了这个配置文件在我们本机环境下的绝对路径。这样他就能根据绝对路径转化为一个输入流。方便我们后续的读配置文件的要求。

在这里插入图片描述

运行完第一行之后,我们的目的就完成了,他最终给我们的是一个输入流。

在这里插入图片描述

第二行(解析xml文件内容)

第二行我们可以看到它其实进入了一个build的重载方法。第二个参数和第三个参数全都是null,他也就是说只传入了我们第一行代码,给过我们的输入流。通过我们的输入流,他给我们建造了一个XMLConfigBuilder对象。这个对象的目的就是用来解析我们的xml的配置文件。就有点类似于我们mymybatis里面的ConfigParse文件。

在这里插入图片描述

因为我们有了这个对象,所以我们可以直接去调用里面的pass方法去解析。所以说这个pass里面的方法基本上囊括了我们xml文件中所有配置的标签。都在这里进行一个解析。

在这里插入图片描述

我们进入到这个方法里面,就可以看到很多熟悉的标签。而xml文件里面能配置的标签基本上都在这里。

在这里插入图片描述

我们再来看一下我们的配置文件长什么样子?

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://masiyi.obmtj0gc1rgs0ho0-mi.oceanbase.aliyuncs.com:3306/test_ob"/><property name="username" value="rootmsy"/><property name="password" value="Msy18719255298"/></dataSource></environment></environments><mappers><mapper resource="mapper/UserMapper.xml"/></mappers>
</configuration>

所以说,我们直接看environments 这个标签里面他就是我们要解析的,其他都是我们没有写,所以他直接就return直接跳过了。

在这里插入图片描述

我们在这个方法里面看到了。他读取到了xml文件里面数据库相关的信息。他都把它存在这里。之后把configuration的Environment这个属性给他set值。

在这里插入图片描述

之后在mapperElement方法里面也解析了我们插面文件里面的mapper节点里面的信息。

在这里插入图片描述

这些操作解析完了之后,我们返回了一个DefaultSqlSessionFactory这个实体类,并且把我们刚刚构建了configuration这个类给赋值进去。所以说这个第二行它的目的就是解析我们的xml文件。并把里面所有的信息都解析出来配置给configuration这个类。

在这里插入图片描述

第三行(构建DefaultSqlSession对象)

在这里插入图片描述

最后进入到了这个openSessionFromDataSource方法,这个方法我里面我们可以看到他通过配置对象进行了很多相关的操作,比如说我们创建一个事物,我们构建事物的对象。如果说熟悉我们自己写框架,我们可以看到它也是New了一个执行器出来。最后他把这些串联出来的对象全部封装成一个DefaultSqlSession对象给返回出去。

在这里插入图片描述

第四行(开始执行查询方法)

熟悉我们自定义框架的同学,看到这一步就知道了。他通过 session.getMapper创建出来的对象其实是一个代理对象。他真正执行的方法都是被我们的mybatis全部给代理了。

我们进入findById这个方法里面可以看到它其实走的我是我们invoke方法。

在这里插入图片描述

到了这一步,可谓我们终于见到了my buddies的庐山真面目,她执行了invoke方法,里面会最终进入到这个方法,这个方法的作用其实就是解析我们的增删改查。例如我们的xml文件里面写的是select方法,它就会走到对应的枚举类里面去。

在这里插入图片描述

相信看到这里的同学已经特别特别特别熟悉了。根据传进来的statement我们可以找到。Configuration里面mappedStatements。对应的MappedStatement

在这里插入图片描述

到了这里。学习了我们jdbc连接MySQL的课程时候就非常的熟悉了。看到这些变量和类,这些不就是我们前面第一节课学到的类吗?

在这里插入图片描述

最终还是通过execute方法,也就是jdbc里面的方法。执行了SQL。最终获得了结果。

在这里插入图片描述

最后根据SQL查询到的结果封装成我们的resultType属性里面对应的类

在这里插入图片描述

至此,我们的课程就学完了。我们已经知道了mybatis的最基本的操作大家感兴趣的可以去我的代码仓库里面去查看详细的代码
https://gitee.com/WangFuGui-Ma/my-mybatis。

哦,对了。感谢博学谷的子慕老师提供的mybatis源码(带注释的内容)。

在这里插入图片描述

另外如果对Elastic Search感兴趣的话,推荐一下我的专栏,这篇专栏介绍了Elasticsearch的Restful API的入门指南。学习如何使用API进行索引、搜索和分析,包括创建索引、定义映射、添加文档、执行查询等。通过实例和代码片段,快速上手Elasticsearch的Restful API,构建强大的搜索功能。感谢大家支持:

Elastic Search的RestFul API入门

在这里插入图片描述

这篇关于【Mybatis】我抄袭了Mybatis,手写一套MyMybatis框架:初窥mybatis源码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/618861

相关文章

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

mybatis中resultMap的association及collectio的使用详解

《mybatis中resultMap的association及collectio的使用详解》MyBatis的resultMap定义数据库结果到Java对象的映射规则,包含id、type等属性,子元素需... 目录1.reusltmap的说明2.association的使用3.collection的使用4.总

mybatis-plus QueryWrapper中or,and的使用及说明

《mybatis-plusQueryWrapper中or,and的使用及说明》使用MyBatisPlusQueryWrapper时,因同时添加角色权限固定条件和多字段模糊查询导致数据异常展示,排查发... 目录QueryWrapper中or,and使用列表中还要同时模糊查询多个字段经过排查这就导致只要whe

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

SpringBoot集成MyBatis实现SQL拦截器的实战指南

《SpringBoot集成MyBatis实现SQL拦截器的实战指南》这篇文章主要为大家详细介绍了SpringBoot集成MyBatis实现SQL拦截器的相关知识,文中的示例代码讲解详细,有需要的小伙伴... 目录一、为什么需要SQL拦截器?二、MyBATis拦截器基础2.1 核心接口:Interceptor

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推