问题描述
Mybatis sql查询日志打印显示有一条数据,转化成实体类时为null
实体类
Dao SQL
通过设置dao xml中 select标签的resultType为DataCollectPushVo自动映射到实体类
问题分析
结果集映射到实体类问题,查看近期git提交记录,代码改动包括mybatis 3.4.0升级3.5.7,引入mybatis-plus,与现有mybatis共用同一个全局配置文件
调试
mybaties查询结果封装 DefaultResultSetHandler 类 handleResultSets方法
sql字段映射实体类属性
createAutomaticMappings()方法获取当前查询结果集中没有在resultMap中映射的字段,以进行自动映射
获取结果集中字段对应的实体类属性名
驼峰转换,去掉字段名中的“_”, JOB_ID变成JOBID
在实体类里面找不到JOBID属性,返回空
字段名转化为大写,大小写不敏感
解决
全局配置类配置关闭字段驼峰映射
启动调试,能获取到结果集中JOB_ID映射到实体类JOB_ID的映射关系
根据autoMapping从结果集(jdbc的rsresult)中取值注入实体类
扩展验证
验证一:自动映射时实体类属性大小写不敏感
开启驼峰式命名,将实体类属性设置为小写
结果:能正确获取到映射关系,并将值注入到实体类
验证二:如果大小写不敏感,结果集的JOB_ID能否同时映射实体类jobid和joBid两个属性中
实体类配置属性 jobid 和 joBid
启动程序查看处理结果:只映射到joBid
跟进属性名获取:反射找到vo类的 MetaClass -> Reflector
在Reflector中 caseInsensitivePropertyMap 用key-value保存vo类每个属性,属性大写名称为key,属性名称为value
caseInsensitivePropertyMap 初始化,第一次调用dao时候初始化,部分在程序启动时就初始化,大写名称相同的属性会覆盖,后一个覆盖前一个,map中的key为“JOBID”的value先是jobid,后被joBid覆盖掉
结论,自动映射(jdbcType=“实体类“)时,结果集根据字段名映射到实体类属性中
- 实体类中属性大小写不敏感,映射时将实体类属性转为大写英文进行匹配;
- 属性名大写相同的属性会有冲突,后面的属性会覆盖前面的属性;
- 开启驼峰式命名配置(mapUnderscoreToCamelCase=true)时,结果集根据字段名会删除下划线再匹配实体类属性;