mybatis的xml解析为sql流程分析

1.解析xml的主流程

解析xml,转换成sqlSession,一切从 SqlSessionFactoryBean 开始:

SqlSessionFactory的初始化: org.mybatis.spring.SqlSessionFactoryBean#afterPropertiesSet

在这里插入图片描述
其中,解析mapper的xml的代码为:
在这里插入图片描述

xml解析的关键链路:

  • org.apache.ibatis.builder.xml.XMLMapperBuilder#parse
  • org.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElement
  • org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode
  • org.apache.ibatis.builder.MapperBuilderAssistant#addMappedStatement

最终,从xml中解析的sql缓存在:
org.apache.ibatis.session.Configuration#mappedStatements
以上为解析的主流程,其中具体的将xml解析成sql的逻辑为XMLStatementBuilder#parseStatementNode ,在下一节详细分析

2.将xml解析成sql

将xml转成sql的关键步骤 是在上述 XMLStatementBuilder#parseStatementNode 中调用LanguageDriver#createSqlSource

对于xml而言,具体的方法路径为:

  • org.apache.ibatis.scripting.xmltags.XMLLanguageDriver#createSqlSource

  • org.apache.ibatis.scripting.xmltags.XMLScriptBuilder#parseScriptNode

  • org.apache.ibatis.scripting.defaults.RawSqlSource#RawSqlSource (创建实例方法)

将xml中的sql片段(如 forech if 等标签)解析成完成的sql的方法:

  • org.apache.ibatis.scripting.defaults.RawSqlSource#getSql
    在这里插入图片描述

不同的标签的解析动作委托给不同的SqlNode实现:
在这里插入图片描述
将转换成的sql进一步解析:
org.apache.ibatis.builder.SqlSourceBuilder#parse
在这里插入图片描述

其转换效果示例为:
转换前:

SELECT
    COUNT (1)
FROM
    POS_AUTH_INFO INFO
WHERE
    MANAGER_ID = # { managerId }
AND AUTH_MANAGER_ID = # { authManagerId }
AND STATUS = # { status }
AND AUTH_PRDT_FLAG = # { authPrdtFlag }

转换后:

SELECT
    COUNT (1)
FROM
    POS_AUTH_INFO INFO
WHERE
    MANAGER_ID = ?
AND AUTH_MANAGER_ID = ?
AND STATUS = ?
AND AUTH_PRDT_FLAG = ?

3.mapper的执行流程

mapper的执行入口:
org.apache.ibatis.binding.MapperMethod#execute
在这里插入图片描述

以查询方法为例,查询方法的关键位置:
org.apache.ibatis.session.defaults.DefaultSqlSession#selectList
在这里插入图片描述
具体的调用链路为(根据实际项目的不同,可能有差异):

  • org.apache.ibatis.executor.CachingExecutor#query
  • org.apache.ibatis.executor.CachingExecutor#query
  • org.apache.ibatis.executor.BaseExecutor#query
  • org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
  • org.apache.ibatis.executor.SimpleExecutor#doQuery
    在这里插入图片描述
  • org.apache.ibatis.executor.statement.RoutingStatementHandler#query
  • org.apache.ibatis.executor.statement.PreparedStatementHandler#query

终极方法调用是:

  • com.alibaba.druid.pool.DruidPooledPreparedStatement#execute
    显然,项目是用到了Druid框架

上述链路中,excutor实现为CachingExecutor , 实际上,根据不同的配置会采用不同的实现,具体参考:

org.apache.ibatis.session.Configuration#newExecutor
在这里插入图片描述

sql中参数的绑定(例如在CachingExecutor#query有调用 ):
org.apache.ibatis.mapping.MappedStatement#getBoundSql

sql中的参数绑定:

org.apache.ibatis.executor.SimpleExecutor#doQuery
org.apache.ibatis.executor.SimpleExecutor#prepareStatement
org.apache.ibatis.scripting.defaults.DefaultParameterHandler#setParameters

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值