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

Posted ubiquitousshare

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实体类属性名和数据库表字段名不对应的几种情况以及解决方式相关的知识,希望对你有一定的参考价值。

今天撸码的时候,遇到了一个问题,以下是数据库表字段和我的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
 */
@Data
public 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手动实现实体类属性名和数据库表字段名的一一映射.

以上是关于实体类属性名和数据库表字段名不对应的几种情况以及解决方式的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis解决字段名与实体类属性名不相同的冲突

MyBatis学习总结——解决字段名与实体类属性名不相同的冲突

MyBatis——解决字段名与实体类属性名不相同的冲突

MyBatis学习总结——解决字段名与实体类属性名不相同的冲突(转载)

MyBatis学习总结——解决字段名与实体类属性名不相同的冲突

MyBatis学习总结——解决字段名与实体类属性名不相同的冲突