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