Mybatis 返回集合类型到底是空集合还是 null?源码解读
Mybatis 作为国内开发中常用到的半自动 orm 框架,相信大家都很熟悉,它提供了简单灵活的 xml 映射配置,方便开发人员编写简单、复杂 SQL,在国内互联网公司使用众多。
本文针对笔者日常开发中对 Mybatis 返回集合类型是否需要判断为 null 结合源码,思考总结而来:
Mybatis版本 3.5.11Spring boot版本 3.0.1github 地址:github.com/wayn111
一、流程图分析
直接给出博主梳理的调用流程图,从用户 dao 方法执行开始,经过 MapperProxy 动态代理,对返回结果进行处理再到结束
其中有几个比较重要的类,我说明一下
MapperMethod对 SQL 执行类型进行判断,判断是 insert、update、delete 还是 select 类型,每个类型的处理流程都不一样PrepareStatementHandler对完成参数替换后的 SQL 语句执行数据库查询,返回 ResultSetDefaultResultHandler对执行结果进行处理转换
二、DefaultResultSetHandler 对返回结果进行处理
在 Mybatis 中 ResultSetHandler 接口用于在 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 对返回结果进行处理:
先创建
DefaultResultHandler对象,初始化list成员属性为空集合在
handleRowValues()方法中,处理返回记录,转换为resultMap对应的对象类型,这个过程中,如果数据库返回不为空,就会调用DefaultResultHandler类中的handlerResult(ResultContext<?> context)方法,将返回对象放入成员属性list集合中调用
defaultResultHandler.getResultList()方法,将成员属性list集合放入multipleResults中,这也就对应了上文提到的multipleResults对象中就包含了我们最终返回的集合对象
四、总结
由上经过源码分析,我们知道 Mybatis 返回集合类型默认是空集合,我们在日常开发中,对于 Mybatis 返回集合类型不需要判断是否为 null,直接调用 list.size() > 0 或者其他第三方工具包提供的集合判空方法即可。
作者:wayn
链接:https://juejin.cn/post/7188878848228851769
来源:稀土掘金










评论