实体类属性名和数据库表字段名不对应的几种情况以及解决方式

今天撸码的时候,遇到了一个问题,以下是数据库表字段和我的POJO实体类.

数据库字段名称:

对应的实体类:

package com.mybatisplus.pojo;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import lombok.Data;import java.io.Serializable;import java.util.Date;/** * @author Adil * @date 2020-03-16 15:04:08 */@Datapublic class User implements Serializable { private static final long serialVersionUID = -6391149300294480283L; @TableId(type = IdType.AUTO) private Integer id; private String username; private Date birthday; private Character sex; private String homeAddress;}

mapper.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.mybatisplus.mapper.UserMapper"><select id="selectUsers" resultType="com.mybatisplus.pojo.User"> select u.id , u.user_name , u.user_birthday , u.user_sex , u.home_address from `user` u</select></mapper>

这里提一点,我在application.yml配置文件中并没有进行任何的关于mybatis的配置,按照我之前的认知,resultType只能适用实体类属性名和数据库表字段名完全一致的情况,也就是说除了id之外,其他属性都应该返回null,然后测试的结果如下:

[{"id":41,"username":"郑爽","birthday":null,"sex":null,"homeAddress":"北京"},
{"id":42,"username":"张天爱","birthday":null,"sex":null,"homeAddress":"北京"},
{"id":43,"username":"迪丽热巴","birthday":null,"sex":null,"homeAddress":"北京"},
{"id":45,"username":"佟丽娅","birthday":null,"sex":null,"homeAddress":"北京"},
{"id":46,"username":"赵丽颖","birthday":null,"sex":null,"homeAddress":"北京"},
{"id":48,"username":"古力娜扎","birthday":null,"sex":null,"homeAddress":"北京"}]

很明显,除了id之外,username和homeAddress属性数据也成功返回了.疑惑的同时我查阅了相关资料,终于搞懂是什么导致了这种情况的发送,那就是我项目使用的是Mybatis-Plus,而不是Mybatis

Mybatis-Plus在实体类属性和数据库表字段映射时,会自动将数据库表字段名中的下划线去掉,并且不受字母大小写的影响,比如user_name和home_address去掉下划线后变为username和homeaddress,Mybatis-Plus会将其映射到实体类属性username和homeAddress上,并且不考虑大小写,这样这两个字段就能成功返回了.而user_birthday和user_sex即使去掉下划线,也不能和实体类属性名birthday和sex保持一致,所以只能返回null.

注意:以上情况适用于Mybatis-Plus,如果你的项目使用的是Mybatis,那么就是另外一种情况了.这里我将pom.xml中Mybatis-Plus的依赖换成了Mybatis又测试了一遍.

xml映射文件不做任何修改,其返回结果如下:

[{"id":41,"username":null,"birthday":null,"sex":null,"homeAddress":null},
{"id":42,"username":null,"birthday":null,"sex":null,"homeAddress":null},
{"id":43,"username":null,"birthday":null,"sex":null,"homeAddress":null},
{"id":45,"username":null,"birthday":null,"sex":null,"homeAddress":null},
{"id":46,"username":null,"birthday":null,"sex":null,"homeAddress":null},
{"id":48,"username":null,"birthday":null,"sex":null,"homeAddress":null}]

发现除了Id正常返回外,其他数据都是null,这就说明Mybatis并没有Mybatis-Plus那么强大了,只要实体类属性名和数据库字段名有所不同,使用resultType就不能映射到.

不过我们可以通过配置,令Mybatis达到Mybatis-Plus的那种强大之处.

在application.yml配置文件中添加Mybatis的配置

mybatis: type-aliases-package: com.mybatisplus.pojo # 实体类包别名作用:可以用实体类名称代替实体类的相对路径 configuration: map-underscore-to-camel-case: true # 驼峰命名

 通过驼峰命名,将数据库表字段名下划线去掉,然后去映射实体类属性名,同样不考虑字母大小写问题,这样就达到了和Mybatis-Plus一样的效果.返回结果如下:

[{"id":41,"username":"郑爽","birthday":null,"sex":null,"homeAddress":"北京"}, {"id":42,"username":"张天爱","birthday":null,"sex":null,"homeAddress":"北京"}, {"id":43,"username":"迪丽热巴","birthday":null,"sex":null,"homeAddress":"北京"}, {"id":45,"username":"佟丽娅","birthday":null,"sex":null,"homeAddress":"北京"}, {"id":46,"username":"赵丽颖","birthday":null,"sex":null,"homeAddress":"北京"}, {"id":48,"username":"古力娜扎","birthday":null,"sex":null,"homeAddress":"北京"}]

当然,依然不能够返回birthday和sex的数据,不过我们可以通过resultMap达到目的.

我们改写xml文件如下:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.mybatisplus.mapper.UserMapper"> <resultMap id="BaseResultMap" type="com.mybatisplus.pojo.User"> <id column="id" property="id"></id> <result column="user_name" property="username"></result> <result column="user_birthday" property="birthday"></result> <result column="user_sex" property="sex"></result> <result column="home_address" property="homeAddress"></result> </resultMap><select id="selectUsers" resultMap="BaseResultMap"> select u.id , u.user_name , u.user_birthday , u.user_sex , u.home_address from `user` u</select></mapper>

这样通过resultMap进行手动一一映射,就可以返回所有字段数据了.测试结果如下:

[{"id":41,"username":"郑爽","birthday":"2019-05-27T09:47:08.000+0000","sex":"男","homeAddress":"北京"},
{"id":42,"username":"张天爱","birthday":"2019-03-02T07:09:37.000+0000","sex":"女","homeAddress":"北京"},
{"id":43,"username":"迪丽热巴","birthday":"2019-03-04T03:34:34.000+0000","sex":"女","homeAddress":"北京"},
{"id":45,"username":"佟丽娅","birthday":"2019-03-04T04:04:06.000+0000","sex":"男","homeAddress":"北京"},
{"id":46,"username":"赵丽颖","birthday":"2018-09-07T09:37:26.000+0000","sex":"男","homeAddress":"北京"},
{"id":48,"username":"古力娜扎","birthday":"2019-03-08T03:44:00.000+0000","sex":"女","homeAddress":"北京"}]

总结:

Mybatis-Plus可以自动映射实体类属性名和数据库表字段名,前提是两者间具有驼峰关系(例如实体类属性名是homeAddress,数据库字段名称是home_address),并且跟字母大小写无关;

Mybatis需要在配置文件中配置驼峰命名,来映射实体类属性名和数据库表字段名,并且跟字母大小写无关,同样,前提是两者间具有驼峰关系;

resultMap手动实现实体类属性名和数据库表字段名的一一映射.

相关文章