千家信息网

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

发表于:2024-09-28 作者:千家信息网编辑
千家信息网最后更新 2024年09月28日,这篇文章主要介绍mybatis-plus查询源码的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!配置详情pom.xmldependency> com.baomi
千家信息网最后更新 2024年09月28日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(){        List genTables =         genTableMapper.selectList(new QueryWrapper<>());    }}

debug流程

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

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

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

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

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.利用同样的方法,又调用了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 handleResultSets(Statement stmt) throws SQLException {    ErrorContext.instance().activity("handling results").object(mappedStatement.getId());    final List multipleResults = new ArrayList<>();    int resultSetCount = 0;    ResultSetWrapper rsw = getFirstResultSet(stmt);    List 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查询源码的示例分析"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

0