mybatis-plus查询源码详解

作者:这个世界太疯狂了 时间:2023-02-02 11:58:02 

配置详情

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

来源:https://blog.csdn.net/weixin_43373818/article/details/123222697

标签:mybatisplus,查询
0
投稿

猜你喜欢

  • Android Usb设备的监听(Dev)外设端口的判定以及耳机的插拔

    2022-12-07 19:23:44
  • Android中Button实现点击换图案及颜色

    2022-06-28 00:42:10
  • springboot 正确的在异步线程中使用request的示例代码

    2023-11-24 22:36:13
  • Java实现分解任意输入数的质因数算法示例

    2022-07-29 23:07:08
  • 史上最全的java随机数生成算法分享

    2023-10-17 15:22:33
  • 简单谈谈java的异常处理(Try Catch Finally)

    2021-08-01 12:40:02
  • java ThreadGroup的作用及方法详解

    2022-02-03 16:49:01
  • Android仿优酷视频的悬浮窗播放效果

    2022-04-30 20:44:51
  • Android实现京东App分类页面效果

    2023-05-07 02:53:49
  • Spring Boot中操作使用Redis实现详解

    2023-11-24 02:39:29
  • SpringBoot打成war包在tomcat或wildfly下运行的方法

    2023-11-23 08:20:56
  • OpenCV实现平均背景法

    2023-06-28 18:25:41
  • C#实现文件上传及文件下载功能实例代码

    2022-12-13 23:57:23
  • Android实现EditText控件禁止输入内容的方法(附测试demo)

    2021-06-26 08:43:38
  • Scala异常处理的方法深入分析

    2022-01-09 19:50:35
  • springboot反爬虫组件kk-anti-reptile的使用方法

    2022-01-09 14:12:59
  • android intent使用定义标题

    2023-11-07 07:06:17
  • slf4j与jul、log4j1、log4j2、logback的集成原理

    2023-01-31 18:01:47
  • Android自定义ScrollView实现阻尼回弹

    2021-11-23 07:20:19
  • JavaWeb入门教程之分页查询功能的简单实现

    2021-11-11 21:52:23
  • asp之家 软件编程 m.aspxhome.com