七张图解锁 Mybatis 整体脉络,让你轻松拿捏面试官
前言
MyBatis 是一款 ORM(Object-Relational Mapping)框架,其主要用于将 Java 对象与关系数据库之间进行映射,凭借其轻量性、稳定性以及广泛的开源社区其受到了广大开发者的追捧。
那 MyBatis 为我们做了哪些事情呢?其实,总结来看主要有如下几点:
SQL 映射配置:MyBatis 使用 XML 或注解配置文件来定义 SQL 查询、插入、更新和删除操作,以及与数据库表之间的映射关系。这使得开发者能够将 SQL 语句与 Java 代码分离,提高了代码的可维护性。
动态 SQL:MyBatis 支持动态 SQL,允许根据不同的条件生成不同的 SQL 语句。这使得构建复杂的查询变得更加灵活和方便。
参数映射:MyBatis 能够将 Java 对象的属性与 SQL 语句中的参数进行映射,无需手动编写繁琐的参数传递代码。
结果集映射:MyBatis 支持将 SQL 查询结果映射到 Java 对象,自动将数据库表中的列值赋给 Java 对象的属性,大大简化了数据的读取和处理。
事务管理:MyBatis 可以与 Java 的事务管理框架(如 Spring)无缝集成,确保数据库操作的原子性和一致性。
连接池集成:MyBatis 可以与常见的 Java 连接池库(如 Apache DBCP、C3P0、HikariCP)集成,以管理数据库连接的获取和释放。
二级缓存:MyBatis 支持二级缓存,可以在多个会话之间共享数据,提高性能。
知晓了 MyBatis 的功能特性后,接下来让我们一起来看看 MyBatis 内部是通过哪些组件来支撑起这些功能的。
总览 MyBatis
对于 Mybatis 的架构大致可以分为三层:基础支持层、核心处理层和接口层。
或许,你会觉得上图过于复杂,难以理解。如果此刻你也有这样的疑惑,不要慌。不妨跟着笔者思路来进行梳理。
首先,使用 MyBatis 概括来看大致包括如下几步:
定义接口,配置相关的 xml 文件信息
加载接口的配置文件,解析相关配置文件
生成接口代理类,执行相关 sql
由于在使用 MyBatis 过程中会编写相关的配置文件,所以 Mybatis 内部必然需要相应组件来支撑配置文件的解析,这些也就构成了底层的基础支撑层。既然会解析配置文件,那是不是必然会涉及到资源加载、配置解析等模块?
进一步,当配置文件解析完成后,下一步就是生成代理,然后执行 sql,此时所涉及的也就是核心处理层中的 sql 执行,sql 解析等。更进一步,执行 sql 过程中为了避免 Connection 频繁创建,是不是需要对连接进行池化操作?所以 MyBatis 内部会抽象出一个数据源模块来统一管理连接。
除此之外,对于 sql 执行过程中的事务是不是也需要控制?所以 MyBatis 还有事务管理模块来对 sql 执行过程中的事务进行管理。
事实上,你只需要记住 Mybatis 的使用过程为:定义接口,提供配置文件,而后生成代理,执行 Sql 即可。以此进行发散,自然而然能扩展出上图所示内容,根本没必要死记硬背。
熟悉了 MyBatis 的整体架构后,我们接下来看 Mybatis 内部执行 sql 的大致流程:
接下来,我们将主要围绕这张图中内容进行总结分析。
配置文件解析
配置文件解析过程大致如下所示:
事实上,MyBatis 内部对于配置文件解析的过程可以概括如下:
加载配置文件:MyBatis 首先加载主配置文件(通常是 mybatis-config.xml),并创建一个 Configuration 对象来表示整个 MyBatis 配置。
解析主配置文件:MyBatis 使用 XML 解析器解析主配置文件,该文件包含了关于数据源、插件、类型别名、缓存等全局配置信息。这些配置会被存储在 Configuration 对象中。
而参与配置文件解析的都继承与 BaseBuilder,其体系结构如下所示:
其中
XMLStatementBuilder:这个类用于解析映射文件中的 <select>、<insert>、<update> 和 <delete> 等标签,构建与 SQL 语句相关的对象(如 MappedStatement),包括 SQL 语句的解析、参数映射、结果映射等。
XMLMapperBuilder:XMLMapperBuilder 用于解析映射文件(通常是 Mapper.xml 文件),负责构建与映射文件相关的对象,包括映射文件的解析、SQL 语句的构建、参数映射、结果映射、缓存配置等。
XMLConfigBuilder:XMLConfigBuilder 用于解析主配置文件(通常是 mybatis-config.xml 文件),负责构建与全局配置相关的对象,包括数据源配置、类型别名配置、插件配置、缓存配置等。
总结来看,对于 MyBatis 的加载过程来说,其在处理配置文件信息时,首先,会传递配置文件所在位置信息,然后再调用框架提供的 SqlSessionFactory 的 build 方法便会根据传入路径信息去加载相关的配置文件,并进行解析。而解析的内容会存放到的 configuration 之中,进而方便后续组件的使用。
代理构建
当配置文件解析,下一步就是通过 SqlSession 的 getMapper 方法来构建一个接口对应的代理类,这一过程大致如下:
这一过程中涉及的组件主要包括 MapperProxyFactory、MapperRegistry、MapperProxy,更加详细的分析可参考 Mybatis 流程分析(六): Mybatis 中方法和 sql 语句的桥梁——MapperProxy, 总之这一过程的本质就是通过 Jdk 动态代理的方式返回一个实现接口的实例对象
sql 执行
当配置文件解析完成,接口相应的代理类构建完毕后,下一步要做的就是 sql 的执行,这一过程逻辑大致如下所示:
这一部分的底层逻辑就是原生 JDBC 操纵数据库的那一套逻辑,即
创建 SQL 语句:即创建 Statement、PreparedStatement 或 CallableStatement 对象,分别用于执行不同类型的 SQL 语句。
执行 SQL 查询:使用创建的 Statement 或 PreparedStatement 对象来执行 SQL 查询。
处理查询结果:通过 ResultSet 对象来处理查询的结果数据。
总结
最后,我们再来一下 Mybatis 内部对于 sql 执行的大致步骤:
创建 SqlSessionFactory:使用 Mybatis 首先需要创建一个 SqlSessionFactory 对象,这通常通过读取 MyBatis 的主配置文件(mybatis-config.xml)并使用 SqlSessionFactoryBuilder 来实现。SqlSessionFactory 负责创建数据库连接和 SqlSession 对象。
创建 SqlSession:通过 SqlSessionFactory 创建一个 SqlSession 对象。SqlSession 代表了与数据库的一次会话,它可以执行 SQL 操作并管理数据库连接。通常,每个线程都会创建自己的 SqlSession。
执行 SQL 语句:在 SqlSession 中,通过调用方法执行 SQL 语句。MyBatis 支持多种方式来执行 SQL,包括 selectOne()、selectList()、insert()、update()、delete() 等方法。
SQL 语句解析:MyBatis 会解析 SQL 语句,包括动态 SQL,参数映射和结果映射。这包括了将 Java 对象转化为 SQL 语句中的参数,以及将查询结果映射回 Java 对象。
执行 SQL:MyBatis 将 SQL 语句发送到数据库,并执行相应的操作,如查询、插入、更新或删除。数据库返回结果或受影响的行数,这取决于 SQL 语句的类型。
处理结果:MyBatis 最终会将 SQL 的执行结果映射为 Java 对象,然后返回给调用者。映射过程通常基于映射文件中的配置。结果集的处理包括将数据库查询结果映射为 Java 对象的属性值。
进一步,上述步骤可总结概括总结为如下的流程。
评论