摘要:本文深入学习了MyBatis的核心原理,包括架构设计、核心组件、执行流程和工作机制。
环境
Windows 10 企业版 LTSC 21H2
MySQL 5.7.40
Java 1.8
Maven 3.6.3
MyBatis 3.5.6
1 架构设计
MyBatis采用分层架构设计,主要分为三个层次。
1.1 接口层(API接口层)
提供给开发者使用的接口,用于执行SQL操作。主要组件包括:
- SqlSession接口:代表一次数据库会话,提供增删改查等数据库操作方法。
- Mapper接口:通过Java接口定义SQL操作,支持XML和注解两种配置方式。
- Configuration类:配置中心,管理所有配置信息。
1.2 核心层(核心处理层)
核心处理层,负责核心操作:
- SQL解析器:解析XML配置和注解配置的SQL语句。
- 参数处理器:处理SQL参数的类型转换和映射。
- SQL执行器:执行SQL语句的核心组件。
- 结果映射器:将查询结果映射到Java对象。
1.3 基础层(基础支撑层)
提供底层支撑,为核心层提供保障:
- 数据源管理:管理数据库连接池。
- 事务管理:处理数据库事务。
- 缓存机制:提供一级缓存和二级缓存。
- 日志系统:记录SQL执行日志。
2 核心组件
2.1 SqlSessionFactoryBuilder
负责根据配置信息构建SqlSessionFactory对象,一旦创建完成,使命即结束,通常作为工具类使用。
特点:
- 构建完成后即可丢弃,不会占用长期资源。
- 线程安全。
- 允许使用不同配置构建多个SqlSessionFactory对象。
2.2 SqlSessionFactory
用于创建SqlSession的核心工厂类,线程安全,通常在整个应用运行期间只有一个对象。
特点:
- 每个应用通常只有一个对象。
- 线程安全,可以被多个线程共享。
- 管理数据库连接池和事务配置。
2.3 SqlSession
代表一次数据库会话,非线程安全,是操作数据库的主要接口,底层封装了Executor对象。
特点:
- 非线程安全,只能在单线程内使用,不能被多个线程共享。
- 使用后必须及时关闭,以释放数据库连接。
- 管理一级缓存(默认开启),同一会话中重复查询可命中缓存。
2.4 Mapper
由Java接口和SQL组成,支持XML和注解两种配置方式。
特点:
- 通过动态代理机制实现。
- 支持XML和注解两种配置方式。
- 自动处理参数映射和结果转换。
2.5 Executor
负责SQL语句的生成和缓存维护,会调用StatementHandler来完成数据库操作。
特点:
- 根据配置可选择三种执行器类型,适应不同场景。
- 管理一级缓存,控制缓存的创建与清除。
- 内部真正的执行者,协调各组件完成数据库操作。
三种基本类型:
- SIMPLE:简单执行器,不做任何处理,直接执行SQL语句。默认执行器。
- REUSE:复用执行器,缓存Statement对象,避免频繁的创建和销毁。
- BATCH:批量执行器,将多条SQL收集后一次性发送到数据库执行,减少网络开销。
2.6 StatementHandler
处理JDBC的Statement,负责设置参数、执行SQL、处理结果集。
特点:
- 采用策略模式,根据StatementType选择具体实现类。
- 提供三种主要实现类,分别对应不同的Statement类型。
- 与ParameterHandler和ResultSetHandler协作,完成参数设置和结果映射。
主要实现类:
- SimpleStatementHandler:负责处理普通Statement,适用于无参数占位符的SQL语句。
- PreparedStatementHandler:负责处理预编译的Statement,适用于有参数占位符的SQL语句。
- CallableStatementHandler:负责处理存储过程的Statement,适用于调用存储过程的SQL语句。
2.7 ParameterHandler
负责将Java方法的参数转换为JDBC需要的参数。
特点:
- 屏蔽参数设置细节,开发者无需手动处理参数占位符。
- 支持配合TypeHandler完成复杂的类型转换。
2.8 ResultSetHandler
负责将JDBC返回的ResultSet结果集转换为Java对象。
特点:
- 需要开发者手动处理结果集的类型转换。
- 支持配合TypeHandler完成复杂的类型转换。
2.9 TypeHandler
负责实现Java类型与JDBC类型之间的双向转换。
特点:
- 内置大量常用类型的TypeHandler转换器。
- 支持自定义转换器处理特殊类型。
2.10 MappedStatement
代表XML和注解中定义的SQL节点,封装了SQL的所有信息,包含了SQL语句、参数映射、结果映射等信息。
特点:
- 每个SQL映射对应一个MappedStatement对象。
- 在配置加载时解析生成,供执行阶段使用。
2.11 Configuration
全局配置类,保存了所有配置信息,贯穿整个执行流程。
特点:
- 持有所有组件的引用。
- 提供访问配置信息的统一入口,是框架运行时的上下文。
3 核心流程
启动流程如下:
启动流程说明:
- 读取配置文件:读取mybatis-config.xml全局配置文件,加载运行环境,以及数据库连接信息。
- 加载映射文件:读取全局配置文件中配置的映射文件,一个配置文件对应一张表。
- 构造会话工厂:通过SqlSessionFactoryBuilder传入配置文件创建SqlSessionFactory会话工厂。
- 创建会话对象:通过SqlSessionFactory会话工厂创建SqlSession会话对象。
- 执行语句方法:调用Executor执行器的方法,从传入MappedStatement对象中获取SQL语句和参数,执行SQL语句。
- 输入参数映射:将输入参数映射到SQL语句中。
- 输出参数映射:将结果映射到输出参数中。
执行流程说明:
- 获取SqlSession对象:从SqlSessionFactory获取数据库会话。
- 获取Mapper代理:通过动态代理创建Mapper接口实现。
- 方法调用:调用Mapper接口方法。
- SQL解析:解析对应的SQL语句和参数映射。
- 参数处理:处理方法参数,转换为SQL参数。
- 执行SQL:通过执行器执行SQL语句。
- 结果映射:将查询结果映射到Java对象。
- 返回结果:返回处理后的结果。
条