mybatis的xml解析为sql流程分析
1.解析xml的主流程
解析xml,转换成sqlSession,一切从 SqlSessionFactoryBean 开始:
SqlSessionFactory的初始化: org.mybatis.spring.SqlSessionFactoryBean#afterPropertiesSet

其中,解析mapper的xml的代码为:

xml解析的关键链路:
org.apache.ibatis.builder.xml.XMLMapperBuilder#parseorg.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElementorg.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNodeorg.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#queryorg.apache.ibatis.executor.CachingExecutor#queryorg.apache.ibatis.executor.BaseExecutor#queryorg.apache.ibatis.executor.BaseExecutor#queryFromDatabaseorg.apache.ibatis.executor.SimpleExecutor#doQuery

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


所有评论(0)