mybatis执行sql过程

发布于:2025-05-11 ⋅ 阅读:(24) ⋅ 点赞:(0)

一、配置加载阶段​

​1. 读取全局配置(mybatis-config.xml)​
  • ​入口类​​:SqlSessionFactoryBuilder.build()
  • ​关键组件​​:
    • XMLConfigBuilder:解析全局配置文件。
    • Configuration:存储所有配置信息(数据源、映射器、插件等)。
  • ​过程​​:
    • 解析 <environments> 标签,创建 DataSource 和 TransactionFactory
    • 解析 <mappers> 标签,加载 Mapper XML 或接口。
​2. 加载 Mapper 文件(UserMapper.xml)​
  • ​入口类​​:XMLMapperBuilder.parse()
  • ​关键组件​​:
    • MappedStatement:每个 SQL 操作的抽象(包含 SQL 文本、参数映射、结果映射等)。
    • SqlSource:动态 SQL 或静态 SQL 的封装。
  • ​过程​​:
    • 解析 <select|insert|update|delete> 标签,生成 MappedStatement
    • 解析动态 SQL(如 <if><foreach>),生成 SqlNode 语法树。
​二、会话创建阶段​
​1. 创建 SqlSessionFactory​
  • ​实现类​​:DefaultSqlSessionFactory
  • ​作用​​:生产 SqlSession(数据库操作入口)。
​2. 创建 SqlSession​
  • ​核心方法​​:openSession()
  • ​关键组件​​:
    • Executor:执行 SQL 的核心组件(默认实现为 SimpleExecutor)。
    • Transaction:事务管理器(JDBC 或 MANAGED)。

​​三、SQL 解析阶段

​1. Mapper 接口代理​
  • ​入口​​:sqlSession.getMapper(UserMapper.class)
  • ​关键组件​​:
    • MapperProxy:动态代理类,拦截接口方法调用。
    • MapperMethod:将方法调用转换为 SQL 操作(SELECT|INSERT|UPDATE|DELETE)。
​2. 生成 BoundSql​
  • ​关键组件​​:
    • SqlSource:通过 DynamicSqlSource 或 RawSqlSource 解析 SQL。
    • BoundSql:最终可执行的 SQL + 参数映射信息。
  • ​过程​​:
    • 替换 ${} 占位符(直接文本替换)。
    • 解析 #{} 占位符,生成 ? 并记录参数映射关系。
​四、参数处理阶段​
​1. 参数绑定​
  • ​关键组件​​:
    • ParameterHandler(实现类:DefaultParameterHandler)
    • TypeHandler:类型转换处理器(如 StringTypeHandler、DateTypeHandler)。
  • ​过程​​:
    • 根据 MappedStatement 中的参数映射(ParameterMapping)解析参数。
    • 使用 TypeHandler 将 Java 对象转换为 JDBC 类型。
    • 通过 PreparedStatement.setXXX() 设置参数。
​2. 动态 SQL 处理​
  • ​示例​​:
<select id="findUsers"> 
    SELECT * FROM users 
    <where> 
    <if test="name != null">AND name = #{name}</if> 
    <if test="age > 18">AND age = #{age}</if> 
    </where> 
</select>
  • ​解析器​​:XMLScriptBuilder 将 <if> 转换为 IfSqlNode
  • ​执行逻辑​​:运行时根据参数值动态拼接 SQL。
​五、SQL 执行阶段​
​1. 执行器(Executor)工作流程​
  • ​核心类​​:BaseExecutor → SimpleExecutor(默认)
  • ​流程​​:
    • 检查一级缓存(LocalCache)是否存在结果。
    • 未命中缓存时,创建 StatementHandler
    • 调用 StatementHandler.prepare() 创建 Statement 对象。
    • 执行 StatementHandler.query() 或 update()
​2. StatementHandler 的类型​

类型

说明

SimpleStatementHandler

处理普通Statement(无参数)

PreparedStatementHandler

处理PreparedStatement(预编译,推荐)

CallableStatementHandler

处理存储过程调用

​3. 执行细节​
  • ​预编译优化​​:
// 生成 PreparedStatement 
Connection conn = session.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
// 设置参数 
parameterHandler.setParameters(ps); 
// 执行查询 
ResultSet rs = ps.executeQuery();

​六、结果映射阶段​
​1. 结果集处理​
  • ​关键组件​​:
    • ResultSetHandler(实现类:DefaultResultSetHandler)
    • ResultMap:定义结果集与 Java 对象的映射规则。
  • ​过程​​:
    • 遍历 ResultSet 的每一行。
    • 根据 ResultMap 创建目标对象(如 User)。
    • 使用 TypeHandler 将数据库字段值填充到对象属性。
​2. 嵌套映射与延迟加载​
  • ​嵌套查询​​:
<resultMap id="userWithOrders" type="User"> 
    <collection property="orders" column="id" select="selectOrdersByUserId"/> 
</resultMap>
  • ​触发时机​​:访问 user.getOrders() 时执行子查询(需开启延迟加载)。

​七、核心组件协作流程图​

​八、高级特性扩展​

​1. 插件机制(Interceptor)​
  • ​拦截点​​:Executor、StatementHandler、ParameterHandler、ResultSetHandler。
  • ​应用场景​​:分页插件、性能监控、SQL 改写。
​2. 二级缓存​
  • ​作用范围​​:Mapper 级别,跨 SqlSession 共享。
  • ​启用条件​​:在 Mapper XML 中添加  标签。
​3. 延迟加载​
  • ​配置​​:在 mybatis-config.xml 中设置:
<settings>
    <setting name="lazyLoadingEnabled" value="true"/>
</settings>

通过理解 MyBatis 的执行原理,可以更好地优化 SQL 性能、定制插件,并快速定位复杂问题(如缓存失效、动态 SQL 错误等)。


网站公告

今日签到

点亮在社区的每一天
去签到