mybatis-plus查詢?cè)创a詳解
配置詳情
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> { }
測(cè)試類
@RunWith(SpringRunner.class) @SpringBootTest(classes = GendemoApplication.class) public class BlockqueueTestDemo { @Autowired GenTableMapper genTableMapper; @Test public void test(){ List<GenTable> genTables = genTableMapper.selectList(new QueryWrapper<>()); } }
debug流程
1.發(fā)現(xiàn) genTableMapper
是一個(gè)代理對(duì)象類型。
2.進(jìn)入代理對(duì)象MybatisMapperProxy
, 調(diào)用其invoke
方法,方法的Class
類型為BaseMapper.selectList()
3.其中cachedInvoker()
方法會(huì)返回一個(gè)PlainMethodInvoker
,它重寫(xiě)了MapperMethodInvoker
接口的invoke()
方法
4.最終會(huì)調(diào)用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.這是經(jīng)過(guò)判斷會(huì)進(jìn)入executeForMany(sqlSession, args)
方法,此時(shí)方法和參數(shù)都顯示出來(lái)了。sqlSession
的類型是SqlSessionTemplate
, 為什么要注意這個(gè) sqlSession
的類型?因?yàn)?code>SqlSession是一個(gè)接口,有很多實(shí)現(xiàn)類,有時(shí)候我們并不知道到底調(diào)用了哪個(gè)實(shí)現(xiàn)類的selectList()
方法,這個(gè)時(shí)候我們看類型就知道了,就可以進(jìn)入SqlSessionTemplate
類,找到selectList()
打上斷點(diǎn),debug就過(guò)來(lái)了。
6.利用同樣的方法,又調(diào)用了DefaultSqlSession
的selectList()
方法。
7.來(lái)到DefaultSqlSession
的selectList()
方法中,此時(shí)已經(jīng)進(jìn)入到mybatis
的源碼范圍了。executor
的類型是MybatisCachingExecutor
8.此時(shí)要注意MybatisCachingExecutor
代理類的handler
是一個(gè)Plugin
9.因?yàn)槲沂褂玫搅朔猪?yè)插件,所以會(huì)來(lái)到com.github.pagehelperPageInterceptor
中
10.由MybatisCachingExecutor
來(lái)執(zhí)行查詢
11.MybatisCachingExecutor
委派 BaseExecutor
執(zhí)行查詢
12.最終委派到PreparedStatementHandler
來(lái)處理
13.最后由DefaultResultSetHandler
來(lái)封裝結(jié)果集
@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); }
總結(jié)
為什么要一層一層的封裝?一層一層的委派?
這里面和緩存有關(guān),有興趣的可以自己了解一下。
下一篇打算記錄一下 mybatis-plus
的自動(dòng)配置過(guò)程,有興趣的可以持續(xù)關(guān)注一下。
文中有錯(cuò)誤的地方不吝賜教謝謝。
到此這篇關(guān)于mybatis-plus查詢?cè)创a走讀的文章就介紹到這了,更多相關(guān)mybatis-plus查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot+redis實(shí)現(xiàn)微博熱搜排行榜的示例代碼
本文主要介紹了springboot+redis實(shí)現(xiàn)微博熱搜排行榜的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05MyBatis配置文件解析與MyBatis實(shí)例演示
這篇文章主要介紹了MyBatis配置文件解析與MyBatis實(shí)例演示以及怎樣編譯安裝MyBatis,需要的朋友可以參考下2022-04-04Springboot日志開(kāi)啟SLF4J過(guò)程解析
這篇文章主要介紹了Springboot日志開(kāi)啟SLF4J過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05JAVA 根據(jù)Url把多文件打包成ZIP下載實(shí)例
這篇文章主要介紹了JAVA 根據(jù)Url把多文件打包成ZIP下載的相關(guān)資料,需要的朋友可以參考下2017-08-08Spring boot 配置多個(gè)redis的方法示例
這篇文章主要介紹了Spring boot 配置多個(gè)redis的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Mybatis實(shí)現(xiàn)自定義類型轉(zhuǎn)換器TypeHandler的方法
Mybatis實(shí)現(xiàn)自定義的轉(zhuǎn)換器非常的簡(jiǎn)單,只需要三步就可以實(shí)現(xiàn)自定義類型轉(zhuǎn)換器TypeHandler,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看下吧2016-07-07SpringCloud之熔斷監(jiān)控Hystrix Dashboard的實(shí)現(xiàn)
這篇文章主要介紹了SpringCloud之熔斷監(jiān)控Hystrix Dashboard的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09