问题描述

        Mybatis sql查询日志打印显示有一条数据,转化成实体类时为null

实体类

full join 结果集 转 java 结果集转化失败_后端

Dao SQL

通过设置dao xml中 select标签的resultType为DataCollectPushVo自动映射到实体类

问题分析

    结果集映射到实体类问题,查看近期git提交记录,代码改动包括mybatis 3.4.0升级3.5.7,引入mybatis-plus,与现有mybatis共用同一个全局配置文件

调试

mybaties查询结果封装 DefaultResultSetHandler 类  handleResultSets方法

full join 结果集 转 java 结果集转化失败_实体类_02

sql字段映射实体类属性

createAutomaticMappings()方法获取当前查询结果集中没有在resultMap中映射的字段,以进行自动映射

full join 结果集 转 java 结果集转化失败_结果集_03

获取结果集中字段对应的实体类属性名

full join 结果集 转 java 结果集转化失败_实体类_04

full join 结果集 转 java 结果集转化失败_字段_05

驼峰转换,去掉字段名中的“_”, JOB_ID变成JOBID

full join 结果集 转 java 结果集转化失败_后端_06

full join 结果集 转 java 结果集转化失败_后端_07

在实体类里面找不到JOBID属性,返回空

full join 结果集 转 java 结果集转化失败_结果集_08

字段名转化为大写,大小写不敏感

full join 结果集 转 java 结果集转化失败_字段_09

解决

全局配置类配置关闭字段驼峰映射

full join 结果集 转 java 结果集转化失败_字段_10

启动调试,能获取到结果集中JOB_ID映射到实体类JOB_ID的映射关系

full join 结果集 转 java 结果集转化失败_字段_11

 根据autoMapping从结果集(jdbc的rsresult)中取值注入实体类

full join 结果集 转 java 结果集转化失败_实体类_12

 

full join 结果集 转 java 结果集转化失败_实体类_13

扩展验证

验证一:自动映射时实体类属性大小写不敏感

开启驼峰式命名,将实体类属性设置为小写

full join 结果集 转 java 结果集转化失败_字段_14

结果:能正确获取到映射关系,并将值注入到实体类

full join 结果集 转 java 结果集转化失败_字段_15

full join 结果集 转 java 结果集转化失败_结果集_16

验证二:如果大小写不敏感,结果集的JOB_ID能否同时映射实体类jobid和joBid两个属性中

实体类配置属性 jobid 和 joBid

full join 结果集 转 java 结果集转化失败_后端_17

 启动程序查看处理结果:只映射到joBid

full join 结果集 转 java 结果集转化失败_结果集_18

 

full join 结果集 转 java 结果集转化失败_实体类_19

 跟进属性名获取:反射找到vo类的 MetaClass  -> Reflector

full join 结果集 转 java 结果集转化失败_字段_20

full join 结果集 转 java 结果集转化失败_字段_21

full join 结果集 转 java 结果集转化失败_后端_22

在Reflector中 caseInsensitivePropertyMap 用key-value保存vo类每个属性,属性大写名称为key,属性名称为value

full join 结果集 转 java 结果集转化失败_字段_23

caseInsensitivePropertyMap 初始化,第一次调用dao时候初始化,部分在程序启动时就初始化,大写名称相同的属性会覆盖,后一个覆盖前一个,map中的key为“JOBID”的value先是jobid,后被joBid覆盖掉

full join 结果集 转 java 结果集转化失败_结果集_24

结论,自动映射(jdbcType=“实体类“)时,结果集根据字段名映射到实体类属性中

  1. 实体类中属性大小写不敏感,映射时将实体类属性转为大写英文进行匹配;
  2. 属性名大写相同的属性会有冲突,后面的属性会覆盖前面的属性;
  3. 开启驼峰式命名配置(mapUnderscoreToCamelCase=true)时,结果集根据字段名会删除下划线再匹配实体类属性;