mybatis-plus 查询,mybatis-plus 代码生成器

  mybatis-plus 查询,mybatis-plus 代码生成器

  

目录

配置详情测试类调试流程总结

 

  

配置详情

pom.xml

 

  依赖关系groupIdcom.baomidou/groupId artifactId my batis-plus-boot-starter/artifactId版本版本/依赖关系映射

  公共接口GenTableMapper扩展BaseMapperGenTable {}

  

测试类

@与(弹簧滑圈)一起运行。class)@ spring boot test(classes=gen demo application。类)公共类BlockqueueTestDemo { @ Autowired gentable mapper gentable mapper;@ Test public void Test(){ ListGenTable genTables=gentable mapper。选择列表(新查询包装());}}

 

  

debug流程

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

 

  2.进入代理对象MybatisMapperProxy,调用其引起方法,方法的班级类型为BaseMapper.selectList()

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

  4.最终会调用MybatisMapperMethod的执行()方法

  公共类MybatisMapperMethod { public Object execute(SQL session SQL session,Object[]args){ Object result;开关(命令。gettype()){ case insert : { Object param=method。convertargstosqlcomandparam(args);result=rowCountResult(SQL会话。插入(命令。getname(),param));打破;}案例更新: { Object param=method。convertargstosqlcomandparam(args);result=rowCountResult(SQL会话。更新(命令。getname(),param));打破;} case delete : { Object param=method。convertargstosqlcomandparam(args);result=rowCountResult(SQL会话。删除(命令。getname(),param));打破;}案例选择:如果(符合

  hod.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.利用同样的方法,又调用了DefaultSqlSessionselectList()方法。

  

 

  7.来到DefaultSqlSessionselectList() 方法中,此时已经进入到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查询内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: