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

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

image.png

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

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

  • Mybatis 版本 3.5.11
  • Spring boot 版本 3.0.1
  • github地址:github.com/wayn111, 欢迎大家关注,点个star

一. 流程图分析

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

image.png

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

  • MapperMethod 对SQL执行类型进行判断,判断是insert、update、delete还是select类型,每个类型的处理流程都不一样
  • PrepareStatementHandler 对完成参数替换后的SQL语句执行数据库查询,返回ResultSet
  • DefaultResultHandler 对执行结果进行处理转换

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

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

image.png

可以看出 Mybatis 先创建 DefaultResultHandler 对象,接着放入 handleRowValues() 方法中,该方法会把数据库查询返回的多条记录转换为 resultMap 对应的对象放入 defaultResultHandler,最后调用 defaultResultHandler.getResultList() 方法将结果放到最终返回需要的 multipleResults 中。multipleResults 对象中就包含了我们最终返回的集合对象,Mybatis 会从 multipleResults 中获取第一个元素作为 MapperProxy 的返回结果

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

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

image.png

  • 里面有一个 list 成员属性,该属性在构造器中由objectFactory对象调用 create(List.class) 方法创建,进入其中
  • image.png
  • resolveInterface(type) 方法中,对传入的类对象做具体转换
  • image.png
  • 可以看到 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 或者其他第三方工具包提供的集合判空方法即可

目录
相关文章
|
4月前
|
安全 Java 应用服务中间件
阿里技术官架构使用总结:Spring+MyBatis源码+Tomcat架构解析等
分享Java技术文以及学习经验也有一段时间了,实际上作为程序员,我们都清楚学习的重要性,毕竟时代在发展,互联网之下,稍有一些落后可能就会被淘汰掉,因此我们需要不断去审视自己,通过学习来让自己得到相应的提升。
|
4月前
|
SQL Java 数据库连接
Mybatis之核心配置文件详解、默认类型别名、Mybatis获取参数值的两种方式
【1月更文挑战第3天】 一、核心配置文件详解 二、默认的类型别名 三、MyBatis的增删改查 四、MyBatis获取参数值的两种方式 1、单个字面量类型的参数 2、多个字面量类型的参数 3、map集合类型的参数 4、实体类类型的参数 5、使用@Param标识参数
62 2
Mybatis之核心配置文件详解、默认类型别名、Mybatis获取参数值的两种方式
|
2月前
|
Java 数据库连接 mybatis
mybatis简单案例源码详细【注释全面】——实体层(User.java)
mybatis简单案例源码详细【注释全面】——实体层(User.java)
14 0
|
5天前
|
SQL 缓存 Java
|
18天前
|
XML Java 数据库连接
探秘MyBatis:手写Mapper代理的源码解析与实现
探秘MyBatis:手写Mapper代理的源码解析与实现
21 1
|
18天前
|
SQL Java 数据库连接
深入源码:解密MyBatis数据源设计的精妙机制
深入源码:解密MyBatis数据源设计的精妙机制
31 1
深入源码:解密MyBatis数据源设计的精妙机制
|
2月前
|
Java 数据库连接 mybatis
mybatis plus字段为null或空字符串把原来的数据也更新了,只需要注解
mybatis plus字段为null或空字符串把原来的数据也更新了,只需要注解
22 0
|
2月前
|
Java 数据库连接 mybatis
mybatis简单案例源码详细【注释全面】——Utils层(MybatisUtils.java)
mybatis简单案例源码详细【注释全面】——Utils层(MybatisUtils.java)
13 0
|
2月前
|
Java 数据库连接 mybatis
mybatis简单案例源码详细【注释全面】——测试层(UserMapperTest.java)
mybatis简单案例源码详细【注释全面】——测试层(UserMapperTest.java)
10 0
|
2月前
|
Java 数据库连接 mybatis
mybatis简单案例源码详细【注释全面】——Dao层映射文件(UserMapper.xml)【重要】
mybatis简单案例源码详细【注释全面】——Dao层映射文件(UserMapper.xml)【重要】
10 0