mybatis-plus查询源码的示例分析
这篇文章主要介绍mybatis-plus查询源码的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
配置详情
pom.xml
dependency>com.baomidou mybatis-plus-boot-starter 3.4.1
mapper
public interface GenTableMapper extends BaseMapper{}
测试类
@RunWith(SpringRunner.class)@SpringBootTest(classes = GendemoApplication.class)public class BlockqueueTestDemo { @Autowired GenTableMapper genTableMapper; @Test public void test(){ ListgenTables = genTableMapper.selectList(new QueryWrapper<>()); }}
debug流程
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
以上是"mybatis-plus查询源码的示例分析"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!