<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
pom.xml
dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency>
mapper
public interface GenTableMapper extends BaseMapper<GenTable> { }
@RunWith(SpringRunner.class) @SpringBootTest(classes = GendemoApplication.class) public class BlockqueueTestDemo { @Autowired GenTableMapper genTableMapper; @Test public void test(){ List<GenTable> genTables = genTableMapper.selectList(new QueryWrapper<>()); } }
1.發現 genTableMapper
是一個代理物件型別。
2.進入代理物件MybatisMapperProxy
, 呼叫其invoke
方法,方法的Class
型別為BaseMapper.selectList()
3.其中cachedInvoker()
方法會返回一個PlainMethodInvoker
,它重寫了MapperMethodInvoker
介面的invoke()
方法
4.最終會呼叫MybatisMapperMethod
的execute()
方法
public class MybatisMapperMethod { public Object execute(SqlSession sqlSession, Object[] args) { Object result; switch (command.getType()) { case INSERT: { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.insert(command.getName(), param)); break; } case UPDATE: { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.update(command.getName(), param)); break; } case DELETE: { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.delete(command.getName(), param)); break; } case SELECT: if (method.returnsVoid() && method.hasResultHandler()) { executeWithResultHandler(sqlSession, args); result = null; } else if (method.returnsMany()) { result = executeForMany(sqlSession, args); } else if (method.returnsMap()) { result = executeForMap(sqlSession, args); } else if (method.returnsCursor()) { result = executeForCursor(sqlSession, args); } else { Object param = method.convertArgsToSqlCommandParam(args); // TODO 這裡下面改了 if (IPage.class.isAssignableFrom(method.getReturnType())) { result = executeForIPage(sqlSession, args); // TODO 這裡上面改了 } else { result = sqlSession.selectOne(command.getName(), param); if (method.returnsOptional() && (result == null || !method.getReturnType().equals(result.getClass()))) { result = Optional.ofNullable(result); } } } break; case FLUSH: result = sqlSession.flushStatements(); break; default: throw new BindingException("Unknown execution method for: " + command.getName()); } if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) { throw new BindingException("Mapper method '" + command.getName() + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); } return result; } }
5.這是經過判斷會進入executeForMany(sqlSession, args)
方法,此時方法和引數都顯示出來了。sqlSession
的型別是SqlSessionTemplate
, 為什麼要注意這個 sqlSession
的型別?因為SqlSession
是一個介面,有很多實現類,有時候我們並不知道到底呼叫了哪個實現類的selectList()
方法,這個時候我們看型別就知道了,就可以進入SqlSessionTemplate
類,找到selectList()
打上斷點,debug就過來了。
6.利用同樣的方法,又呼叫了DefaultSqlSession
的selectList()
方法。
7.來到DefaultSqlSession
的selectList()
方法中,此時已經進入到mybatis
的原始碼範圍了。executor
的型別是MybatisCachingExecutor
8.此時要注意MybatisCachingExecutor
代理類的handler
是一個Plugin
9.因為我使用到了分頁外掛,所以會來到com.github.pagehelperPageInterceptor
中
10.由MybatisCachingExecutor
來執行查詢
11.MybatisCachingExecutor
委派 BaseExecutor
執行查詢
12.最終委派到PreparedStatementHandler
來處理
13.最後由DefaultResultSetHandler
來封裝結果集
@Override public List<Object> handleResultSets(Statement stmt) throws SQLException { ErrorContext.instance().activity("handling results").object(mappedStatement.getId()); final List<Object> multipleResults = new ArrayList<>(); int resultSetCount = 0; ResultSetWrapper rsw = getFirstResultSet(stmt); List<ResultMap> resultMaps = mappedStatement.getResultMaps(); int resultMapCount = resultMaps.size(); validateResultMapsCount(rsw, resultMapCount); while (rsw != null && resultMapCount > resultSetCount) { ResultMap resultMap = resultMaps.get(resultSetCount); handleResultSet(rsw, resultMap, multipleResults, null); rsw = getNextResultSet(stmt); cleanUpAfterHandlingResultSet(); resultSetCount++; } String[] resultSets = mappedStatement.getResultSets(); if (resultSets != null) { while (rsw != null && resultSetCount < resultSets.length) { ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]); if (parentMapping != null) { String nestedResultMapId = parentMapping.getNestedResultMapId(); ResultMap resultMap = configuration.getResultMap(nestedResultMapId); handleResultSet(rsw, resultMap, null, parentMapping); } rsw = getNextResultSet(stmt); cleanUpAfterHandlingResultSet(); resultSetCount++; } return collapseSingleResultList(multipleResults); }
為什麼要一層一層的封裝?一層一層的委派?
這裡面和快取有關,有興趣的可以自己瞭解一下。
下一篇打算記錄一下 mybatis-plus
的自動設定過程,有興趣的可以持續關注一下。
文中有錯誤的地方不吝賜教謝謝。
到此這篇關於mybatis-plus查詢原始碼走讀的文章就介紹到這了,更多相關mybatis-plus查詢內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45