温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

mybatis-plus查询源码的示例分析

发布时间:2022-03-02 14:33:28 来源:亿速云 阅读:349 作者:小新 栏目:开发技术

这篇文章主要介绍mybatis-plus查询源码的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

配置详情

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<>());     } }

debug流程

1.发现 genTableMapper 是一个代理对象类型。

mybatis-plus查询源码的示例分析

2.进入代理对象MybatisMapperProxy , 调用其invoke 方法,方法的Class类型为BaseMapper.selectList()

mybatis-plus查询源码的示例分析

3.其中cachedInvoker()方法会返回一个PlainMethodInvoker ,它重写了MapperMethodInvoker 接口的invoke()方法

mybatis-plus查询源码的示例分析

4.最终会调用MybatisMapperMethodexecute()方法

mybatis-plus查询源码的示例分析

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就过来了。

mybatis-plus查询源码的示例分析

6.利用同样的方法,又调用了DefaultSqlSessionselectList()方法。

mybatis-plus查询源码的示例分析


7.来到DefaultSqlSessionselectList() 方法中,此时已经进入到mybatis的源码范围了。executor的类型是MybatisCachingExecutor

mybatis-plus查询源码的示例分析

8.此时要注意MybatisCachingExecutor 代理类的handler是一个Plugin

mybatis-plus查询源码的示例分析

mybatis-plus查询源码的示例分析

9.因为我使用到了分页插件,所以会来到com.github.pagehelperPageInterceptor

mybatis-plus查询源码的示例分析

10.由MybatisCachingExecutor来执行查询

mybatis-plus查询源码的示例分析

11.MybatisCachingExecutor 委派 BaseExecutor 执行查询

mybatis-plus查询源码的示例分析

mybatis-plus查询源码的示例分析

12.最终委派到PreparedStatementHandler来处理

mybatis-plus查询源码的示例分析

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查询源码的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI