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

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐