概述
mybatis
是一个常用的持久层框架;通常搭配mysql
使用;
在将查询结果映射成一个复杂vo
的时候,通常会用到resultMap
,在其中嵌套association
和collection
等操作;将一个复杂查询拆分成简单查询;
在vo
中的变量有时候会定义初始值,那么当mybatis
中查询结果为null
的时候,会覆盖这个初始值吗;
mybatis版本:3.5.10
mysql版本:8.0.32
源码分析
映射结果集入口
org.apache.ibatis.executor.resultset.ResultSetHandler
public interface ResultSetHandler {// 处理结果集,生成相应的结果对象集合<E> List<E> handleResultSets(Statement stmt) throws SQLException;// 处理结果集,返回游标对象<E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;// 处理储存过程的输出参数 void handleOutputParameters(CallableStatement cs) throws SQLException;
}
进入实现类
org.apache.ibatis.executor.resultset.DefaultResultSetHandler
结果集的处理方法
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
捞一张网图
一般都只会返回一个结果集,再进一步观察,里面调用的都是handleRowValues
方法,在该方法中区分了嵌套ResultMap
和普通ResultMap
(包括普通的resultType
也会转成ResultMap
,只是框架自动帮你转了)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSet
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleRowValues
handleRowValuesForSimpleResultMap
:处理简单的结果集映射
handleRowValuesForNestedResultMap
:处理嵌套的结果集映射(resultMap> 声明时 是否包含 association、collection、case 关键字
)
在最后映射的时候都是调用了
如果开启了自动映射,对实例进行自动赋值
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#applyAutomaticMappings
对用户主动声明的属性进行映射
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#applyPropertyMappings
在赋值的时候可以看到图中判断;
configuration.isCallSettersOnNulls()
代表配置中null
值是否调用set
方法,顾名思义;
我的配置中se
t为true
;
#mybatis plus 设置
mybatis-plus:configuration:# 返回类型为Map,显示null对应的字段call-setters-on-nulls: true
所以如果返回vo
中想要在查询结果为null
时,不覆盖vo
的值;
- 改配置
- 将
vo
字段类型改为基础类型