Mybatis-DyanmicSqlSourcce
Mybatis DyanmicSqlSourcce
-
Author: HuiFer
-
源码阅读工程: SourceHot-Mybatis
-
org.apache.ibatis.scripting.xmltags.DynamicSqlSource
-
org.apache.ibatis.scripting.xmltags.DynamicContext.DynamicContext
|
|
|
|
-
根据 mapper.xml 文件中的代码流程 需要走
org.apache.ibatis.scripting.xmltags.StaticTextSqlNode#apply
org.apache.ibatis.scripting.xmltags.TrimSqlNode#apply
org.apache.ibatis.scripting.xmltags.IfSqlNode#apply
|
|
-
org.apache.ibatis.scripting.xmltags.DynamicContext#appendSql
1 2 3
public void appendSql(String sql) { sqlBuilder.add(sql); }
-
解析
trim
标签
-
在解析
trim
的时候会往下解析下级标签1 2 3 4 5 6 7 8
@Override public boolean apply(DynamicContext context) { FilteredDynamicContext filteredDynamicContext = new FilteredDynamicContext(context); // 解析下级标签的入口 boolean result = contents.apply(filteredDynamicContext); filteredDynamicContext.applyAll(); return result; }
|
|
evaluator.evaluateBoolean(test, context.getBindings())
方法
|
|
|
|
存在返回true
执行完成就得到了一个 sql
继续执行org.apache.ibatis.scripting.xmltags.DynamicSqlSource#getBoundSql
方法
-
发送 sql
org.apache.ibatis.executor.SimpleExecutor#doQuery
-
调用链路如下
-
org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
-
org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
-
org.apache.ibatis.executor.Executor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
-
org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
@SuppressWarnings("unchecked") @Override public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId()); if (closed) { // 判断当前是否关闭 throw new ExecutorException("Executor was closed."); } if (queryStack == 0 && ms.isFlushCacheRequired()) { // 查询堆栈==0 和 是否需要刷新缓存 // 清理本地缓存 clearLocalCache(); } List<E> list; try { // 堆栈+1,防止重新清理缓存 queryStack++; // 通过 缓存key 在本地缓存中获取 list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; if (list != null) { // 通过缓存 key 查到后处理 localOutputParameterCache handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); } else { // 没有查询到从数据库查询 list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); } } finally { // 堆栈-1 queryStack--; } if (queryStack == 0) { for (DeferredLoad deferredLoad : deferredLoads) { deferredLoad.load(); } // 清空线程安全队列(延迟队列) // issue #601 deferredLoads.clear(); if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) { // STATEMENT 清空本地缓存 // issue #482 clearLocalCache(); } } return list; }
-
org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
1 2 3 4 5 6 7 8 9 10 11 12 13 14
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List<E> list; localCache.putObject(key, EXECUTION_PLACEHOLDER); try { list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } finally { localCache.removeObject(key); } localCache.putObject(key, list); if (ms.getStatementType() == StatementType.CALLABLE) { localOutputParameterCache.putObject(key, parameter); } return list; }
org.apache.ibatis.executor.BaseExecutor#doQuery
org.apache.ibatis.executor.SimpleExecutor#doQuery
-
-
|
|
org.apache.ibatis.executor.statement.BaseStatementHandler#prepare
org.apache.ibatis.executor.statement.PreparedStatementHandler#instantiateStatement
|
|
|
|
-
这个方法都去了
java.sql.Connection#prepareStatement(java.lang.String, java.lang.String[])
-
接下来需要考虑的问题是如何将
?
换成我们的参数2
-
org.apache.ibatis.executor.statement.StatementHandler#parameterize
org.apache.ibatis.executor.statement.RoutingStatementHandler#parameterize
org.apache.ibatis.executor.statement.StatementHandler#parameterize
org.apache.ibatis.executor.statement.PreparedStatementHandler#parameterize
org.apache.ibatis.executor.parameter.ParameterHandler
org.apache.ibatis.scripting.defaults.DefaultParameterHandler#setParameters
这样就拿到了value
的值
准备工作就绪了发送就可以了
doQuery
的工作完成了继续往下走
|
|
org.apache.ibatis.executor.statement.RoutingStatementHandler#query
org.apache.ibatis.executor.statement.PreparedStatementHandler#query
org.apache.ibatis.executor.resultset.ResultSetHandler#handleResultSets
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
处理后结果如上
|
|
- 原文作者:知识铺
- 原文链接:https://index.zshipu.com/geek/post/code/docs/Mybatis/%E6%A0%B8%E5%BF%83%E5%A4%84%E7%90%86%E5%B1%82/Mybatis-DyanmicSqlSourcce/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com