从一个BUG学习resultType和resultMap以及字段映射的一些配置
今天帮Java小同学解决了一个mybatis查询映射时小Bug,说是Bug其实更多是代码不规范,没熟悉代码导致的错误,虽然很简单,但也浪费了半天时间。这种问题对于后端新手接手一个二手项目应该会经常遇到,记录备忘。
先上代码问题:
@Data
public class OrderDetail {
private Integer id;
private BigDecimal remuneration;
private String idCard;
private String contactNumber;
private Integer orderStatus;
private Date addTime;
private Date updateTime;
}
XML代码如下:
<resultMap id="BaseResultMap" type="com.project.model.OrderDetail" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="remuneration" property="remuneration" jdbcType="DECIMAL" />
<result column="id_card" property="idCard" jdbcType="VARCHAR" />
<result column="contact_number" property="contactNumber" jdbcType="VARCHAR" />
<result column="order_status" property="orderStatus" jdbcType="INTEGER" />
<result column="add_time" property="addTime" jdbcType="TIMESTAMP" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Base_Column_List" >
id, emuneration, id_card, contact_number, order_status, add_time, update_time
</sql>
<select id="selectByOrderId" resultType="com.project.model.OrderDetail">
select
<include refid="Base_Column_List"/>
from order_detail
where order_id = #{orderId}
</select>
上述代码selectByOrderId方法查出来的orderDetail只有id和remuneration成功映射,其余字段均为null
Java大牛应该从上述结论瞬间定位到问题:
mybatis忘记配置下划线转驼峰的配置
作为业余选手,完全没注意到上面只有id和remuneration这俩不带下划线的有值,其余为null的特征。还是从xml到pojo一路排查了个遍,确定了不是字段不一致的原因。
没发现问题之前整了俩方案也能解决问题:
- 将select内项设置别名解决了
<select id="selectByOrderId" resultType="com.project.model.OrderDetail">
select
id, emuneration, id_card as idCard, contact_number as contactNumber, order_status as orderStatus,
add_time as addTime, update_time as updateTime
from order_detail
where order_id = #{orderId}
</select>
- 将resultType改为resultMap
<select id="selectByOrderId" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from order_detail
where order_id = #{orderId}
</select>
解决了问题之后,看了下文档对 resultType和resultMap的解释
resultType期望从这条语句中返回结果的类全限定名或别名,对于SQL语句查询出的字段在相应的pojo中必须有相同的字段对应。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。
resultMap对外部 resultMap 的命名引用。
果然在出BUG是使用resultType,我们的下划线字段名和pojo中驼峰字段名肯定没有对应上。模糊的记得好像有配置可以设置mybatis映射结果下划线转换为驼峰。仔细翻了下mybatis文档,发现配置如下:
mybatis.configuration.map-underscore-to-camel-case=true
<configuration>
<!-- 全局配置 -->
<settings>
<!-- 是否开启自动驼峰命名规则(camel case)映射,即从数据库列名 A_COLUMN 到属性名 aColumn 的类似映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
注意: 当resultType = hash时,上述配置无效,此时最好使用resultMap