写点什么

Mybatis 返回集合类型到底是空集合还是 null?源码解读

  • 2023-04-24
    湖南
  • 本文字数:1537 字

    阅读完需:约 5 分钟

Mybatis 作为国内开发中常用到的半自动 orm 框架,相信大家都很熟悉,它提供了简单灵活的 xml 映射配置,方便开发人员编写简单、复杂 SQL,在国内互联网公司使用众多。


本文针对笔者日常开发中对 Mybatis 返回集合类型是否需要判断为 null 结合源码,思考总结而来:

一、流程图分析

直接给出博主梳理的调用流程图,从用户 dao 方法执行开始,经过 MapperProxy 动态代理,对返回结果进行处理再到结束

其中有几个比较重要的类,我说明一下

  • MapperMethod 对 SQL 执行类型进行判断,判断是 insert、update、delete 还是 select 类型,每个类型的处理流程都不一样

  • PrepareStatementHandler 对完成参数替换后的 SQL 语句执行数据库查询,返回 ResultSet

  • DefaultResultHandler 对执行结果进行处理转换

二、DefaultResultSetHandler 对返回结果进行处理

MybatisResultSetHandler 接口用于在 StatementHandler 对象执行完查询操作或存储过程后,对结果集或存储过程的执行结果进行处理。同理,当返回集合类型时,Mybatis 最后也会交给 ResultSetHandler 的实现类 DefaultResultSetHandler 来处理,最终在 handleResultSet() 方法中完成对返回集合类型的处理,如下图:

可以看出 Mybatis 先创建 DefaultResultHandler 对象,接着放入 handleRowValues() 方法中,该方法会把数据库查询返回的多条记录转换为 resultMap 对应的对象放入 defaultResultHandler,最后调用 defaultResultHandler.getResultList() 方法将结果放到最终返回需要的 multipleResults 中。


multipleResults 对象中就包含了我们最终返回的集合对象,Mybatis 会从 multipleResults 中获取第一个元素作为 MapperProxy 的返回结果。

三、DefaultResultHandler 一个包含实际要返回集合对象的处理类

在上面代码中有一个非常重要的类,那就是 DefaultResultHandler 类,实际上我们返回的集合对象就是 DefaultResultHandler 内部的成员属性 list ,查看源码:

  • 里面有一个 list 成员属性,该属性在构造器中由objectFactory对象调用 create(List.class) 方法创建,进入其中

resolveInterface(type) 方法中,对传入的类对象做具体转换:

可以看到 List.class 被转换为 ArrayList.class,接着调用 instantiateClass() 方法,完成空集合的创建,(划重点)由此可见,Mybatis 返回集合类型默认是空集合

  • handlerResult(ResultContext<?> context) 方法,该方法会往 list 中添加元素

  • getResultList() 方法,直接返回 list 成员属性


结合上面提到的最后调用 defaultResultHandler.getResultList() 方法将结果放到最终返回需要的 multipleResults 中,我们很容易就能知道,我们返回的集合对象实际上就是 DefaultResultHandler 类中的 list 属性,然后我们重新梳理下上文中第二部分:


DefaultResultSetHandler 对返回结果进行处理:

  1. 先创建 DefaultResultHandler 对象,初始化 list 成员属性为空集合

  2. handleRowValues() 方法中,处理返回记录,转换为 resultMap 对应的对象类型,这个过程中,如果数据库返回不为空,就会调用 DefaultResultHandler 类中的 handlerResult(ResultContext<?> context) 方法,将返回对象放入成员属性 list 集合中

  3. 调用 defaultResultHandler.getResultList() 方法,将成员属性 list 集合放入multipleResults,这也就对应了上文提到的 multipleResults 对象中就包含了我们最终返回的集合对象

四、总结

由上经过源码分析,我们知道 Mybatis 返回集合类型默认是空集合,我们在日常开发中,对于 Mybatis 返回集合类型不需要判断是否为 null,直接调用 list.size() > 0 或者其他第三方工具包提供的集合判空方法即可。


作者:wayn

链接:https://juejin.cn/post/7188878848228851769

来源:稀土掘金

用户头像

还未添加个人签名 2021-07-28 加入

公众号:该用户快成仙了

评论

发布
暂无评论
Mybatis返回集合类型到底是空集合还是null?源码解读_Java_做梦都在改BUG_InfoQ写作社区