Mybatis 原理之启动阶段都干了啥

本文详细介绍了阅读MyBatis源码的学习思路,并且对源码做了详细注释,讲解了整个Mybatis的启动过程。

本文篇幅较长,所以先来一张 PLMM 让大脑兴奋下,建议收藏阅读,非常适合用于面试前的重点复习。大脑兴奋了吧,接下来吃偷 Mybatis。

为什么学?如何学?

为什么要阅读MyBatis源码?因为作为当前最热门的经典ORM框架,在所有框架里Mybatis源码可以说是最简单易懂的,非常适合上手阅读,而且Mybatis也是面试中常问的知识点,必须要掌握。

如何去学习MyBatis源码呢?

所有框架和技术的学习都一样,按照"大胆假设,小心求证"的思路,先问自己几个问题。

在MyBatis出现之前软件开发中存在什么问题?怎么解决这个问题?如果是你怎么做?别人(MyBatis)怎么做?

JDBC 执行流程

因为所有的ORM框架其根本都需要依赖于JDBC与MySQL服务器进行交互,所以再次回顾一下JDBC的整个执行流程。

public static void main(String[] args) throws Exception {

    //1. 加载驱动程序
    Class.forName("com.mysql.jdbc.Driver");
    //2. 获得数据库连接
    Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
    //3. 操作数据库,实现增删改查
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM emp");
    while(rs.next()){
        System.out.println(rs.getString("name")+" -"+rs.getInt("age"));
    }
}

从上述JDBC的demo可以看出,JDBC执行主要有以下核心流程。

  1. 加载驱动程序

  2. 连接数据源,建立数据库连接connection。

  3. 准备SQL,建立statement

  4. 向数据库发送命令,执行SQL。

  5. 处理数据库响应并返回结果。

  6. 关闭资源。

存在了什么问题?

通常来说,一个框架就是解决了两个问题。一是降低代码冗余度,降低使用难度;二是解耦,让开发者更专注于业务开发。

目前在项目生产中,直接使用到JDBC的时候大家可以明显感觉到存在几个问题:

  1. JDBC的API使用繁琐,接口使用难度高,方法不便于复用,对业务侵入度高。

  2. 数据库的配置信息难以维护。

  3. 对于表结构和Java对象的关系难以维护。

  4. 编写原生SQL繁琐容易出错且不安全,难以复用。

我会如何设计?

类似的,如果我去实现Mybatis 如何去做呢?核心步骤一定脱离不开JDBC,这是一切ORM框架和数据库操作的基础,所以扩展应该基于此展开。

既然需要解决配置繁琐的问题,那就需要将配置信息封装到一起;JDBC使用复杂,那就将JDBC接口做更高一层的封装;Java对象和表结构的关系难以维护那就采用ORM思想增加对应配置,作为实体与表结构的映射;SQL难以复用和编写,那就将SQL独立出来配置,让开发人员专注于SQL的编写和优化。

总结来说如果需要解耦合,那就增加一个中间层,需要灵活复用,就增加映射配置。

所以我们可以推断MyBatis的流程如下:

  1. 配置实体关系映射文件,以及对应SQL配置映射文件,配置数据库配置文件。

  2. 读取配置,并且解析,将配置实例化为对象。

  3. 通过配置信息建立transaction,建立statement。

  4. 对于SQL的执行流程,因为对于SQL的解析逻辑和流程是一样的,可以用动态代理模式+模版模式生成执行类,代理执行。

  5. 替换SQL中的参数,生成实际SQL,执行SQL

  6. 拿到执行结果,通过映射文件解析结果,并且生成Java对象。

1-3是启动流程,4-5是每次的执行流程。

MyBatis 核心流程如何做?

Mybatis的核心流程氛围两个阶段,启动准备阶段和执行SQL阶段。

  1. 加载配置XMl文件。

  2. 读取mybatis的dtd描述文件,并且解析xml标签

  3. 通过读取的XMl配置信息生成对应的全局配置对象,以及生成mapper不同方法的SQL映射。

  4. 创建 SqlSessionFactory 完成,使用 SqlSessionFactory 创建 Session。

  5. 根据方法签名,获得mapper对应的代理对象。

  6. 通过JDK动态代理找到实现类,获得数据库连接,然后执行SQL。

  7. 拿到执行结果,并且根据映射关系处理为Java对象。

  8. 执行结束,关闭资源。

其中重点在于5个点:解析xml、生产代理对象、获得代理对象、执行SQL、处理结果集。

源码调试用例

首先准备数据库数据:

CREATE TABLE `user_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT '',
  `age` int(11) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into user_info values(1,'后端开发技术',20,'2022-06-14 12:00:00');

建立测试用例,看一下如何手动启动MyBatis,以下代码依据官网给出的用例进行了改造。具体代码不完整贴出来了,比较简单。

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 根据全局配置文件创建出SqlSessionFactory
// SqlSessionFactory:负责创建SqlSession对象的工厂
// SqlSession:表示跟数据库建议的一次会话
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

// =================================================================
// 获取数据库的会话,创建出数据库连接的会话对象(事务工厂,事务对象,执行器,如果有插件的话会进行插件的解析)
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取要调用的接口类,创建出对应的mapper的动态代理对象
UserDao mapper = sqlSession.getMapper(UserDao.class);
// 调用方法开始执行
User userInfo = mapper.findUserInfo(1);

上半部分是启动和准备过程,下半部分是执行SQL过程。

启动准备阶段流程

这个阶段我们重点解读以下流程:

  1. 加载配置XMl文件

  2. 读取mybatis的dtd描述文件,并且解析xml标签

  3. 通过读取的XMl配置信息生成对应的全局配置对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值