面试题——当实体类中的属性名和表中的字段名不一样,如何将查询的结果封装到指定 pojo?

在使用MyBatis的时候,应该注意实体类的属性名尽量和表的字段名尽量相同,如果不同将会导致MyBatis无法完成数据的封装,但是在软件开发过程中,数据库的创建和软件环境的搭建不可能是同一个人,实体类属性名和数据库的字段名不同那就在所难免。

  • pojo指简单的Java对象, 是实体类entity和值对象VO 还有数据传输对象DTO的统称

MyBatis只能自动维护库表”列名“与”属性名“相同时的一一对应关系,二者不同时,无法自动ORM。

  • Java的变量命名规范是:驼峰命名法
  • 数据库的列名命名规范是:下划线区分单词命名法

这样Java实体类和数据库列名不一致就成了一种常态,只有数据库中的字段和实体类的属性名字对得上的字段,才能被查出来。

解决方案一:命名一致

我们可以把POJO中的实体类命名和数据库表中字段的命名调整一致,但是数据库表字段的命名方式并不是驼峰式命名方式,不符合Java中对于类属性的命名规则,因此不推荐使用。

解决方案二:给表中字段取别名

我们可以通过在表对应的mapper.xml配置文件中通过<sql>标签给字段取别名的方式,使得重新命名的表字段别名与实体类中的属性名保持一致,再通过<include>标签引入sql代码块,这样也可以达到数据正常封装的效果。

通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类 的属性名一致。 

优点:

  • 1.便于理解
  • 2.如果要查询的字段有重名的情况,使用别名可以区分开来

缺点: 

  • 1.如果列数过多会导致语句难以阅读
  • 2.如果查询语句的定义多个,会导致重复代码增多,多次定义显示列增加了工作量
<mapper namespace="com.cos.mybatis.ManagerDao">
    <select id="selectManagerByIdAndPwd" resultType="com.qf.mybatis.part2.orm.Manager">
        SELECT mgr_id AS id , mgr_name AS username , mgr_pwd AS password
        FROM t_managers
        WHERE mgr_id = #{id} AND mgr_pwd = #{pwd}
    </select>
</mapper>

起别名的三种方法: 

  • 1.使用as关键字
  • 2.省略as关键字,使用空格
  • 3.如果你要取的别名是个mysql的关键字,或者取的别名中包含特殊符号,比如像空格,像#井号;#井号在mysql中是注释符号#(解决办法是把别名用引号引起来,引号可以是双引号,也可以是单引号,建议使用双引号)

解决方案三:通过resultMap来调整字段名与属性名映射一致

我们可以通过<resultMap>标签来将数据库表中字段映射到对应的实体类属性上,完成数据库查询数据的封装,如果实体类的属性中存在自定义类属性,那么也可以通过resultMap进行数据的层层映射,封装到对应自定义类中的基本类型数据中。

  • 通过< resultMap id="" type="" >映射,匹配列名与属性名。

    resultMap 用于指定某个自定义的封装规则,MyBatis会根据这个自定义的封装规则进行数据封装(单条记录)

  • 优点:这个自定义的封装规则可以被重复使用,省去多次定义别名的问题
  • 缺点:需要额外定义一套封装规则的resultMap
<select id="getOrder" parameterType="int"
resultMap="orderresultmap">
select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!–用 id 属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用 result 属性来映射非主键字段,property 为实体类属性名,column
为数据表中的属性–>
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>

resultMap   id: 唯一标识

type: 映射类型可以是别名的形式

result:映射一般的字段

id:映射主键 不一样的才会采用映射

column:数据库字段名      property:实体字段名

解决方案四:使用Mybatis特殊设置

在Mybatis配置文件<settings>标签内设置mapUnderscoreToCamelCase属性的值为true,那么数据库就会将表字段的分割式命名(例如:p_id)自动映射到实体类的驼峰式命名(例如:pId)上,且不区分驼峰式命名的大小写。

注意:此方法仅适用于字段名的下划线转化为驼峰后恰好与类的属性名一致的情况

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

解决方案五

1、使用注解@TableName (value = ...)
当数据库名与实体类名不一致或不符合驼峰命名时,需要在此注解指定表名(不加这个注解默认将实体类的小写形式在db中寻找)

@TableName(value = "user")
public class AnnotationUser4Bean {
@TableId(value = "user id",type = IdType.AUTO)
private String userId;
@TableField("name")
private String name;
@TableField("sex")
private string sex;
@TableField("age")
private Integer age;

2、使用@TableField注解

该注解用于标识非主键的字段。将数据库列与 JavaBean 中的属性进行映射

  1. 主要用来解决实体类的字段名与数据库中的字段名不匹配的问题(数据库user_addr,字段useraddr未驼峰)
  2. 实体类中的属性字段在表中不存在的问题

3、在 Mapper 接口中使用注解方式配置映射关系,使用 @Results@Result 注解配置映射关系。

首先说明一下

@Results各个属性的含义,id为当前结果集声明唯一标识,value值为结果集映射关系;

@Results 注解可用于定义多个列和Java对象属性之间的映射关系。

比如,我们在查询用户表时,需要将 id、 username 和 password 的值映射到 User 对象的userId、 userName 和 password 属性上,可以在 @Select 注解内使用 @Results 注解完成;

@Results注解需要指定 column 和 property 属性,分别代表数据库列名和Java对象属性名; 

@Results({
        @Result(property = "name", column = "user_name"),
        @Result(property = "age", column = "user_age")
})
@Select("SELECT user_name, user_age FROM user WHERE id = #{id}")
User getUserById(@Param("id") int id);

@Result 注解用于定义单个列和Java对象属性之间的映射关系。一般情况下,它会被用在Results 注解内,也可以单独使用。@Result 注解也需要指定 column 和 property 属性

@Result(column = "id", property = "userId")
public User findById(Long id);

@Result代表一个字段的映射关系,column指定数据库字段的名称,propery指定实体类属性的名称,jdbcType数据库字段类型,@Result里的id值为true表明主键,默认false;

参考

注解@TableName、@TableField_数据库不转驼峰注解_GuochaoHN的博客-CSDN博客

【Mybatis】数据封装时数据库表字段和POJO中实体类属性命名不一致的几种解决方案_mybatis po 属性大小写不一样_Edward朱or猪的博客-CSDN博客

Mybatis框架之解决列名(表中的字段名称)和实体类中的属性名不一致_Nice康的博客-CSDN博客 Mybatis:解决属性名和字段名不一致的问题_Ariverh的博客-CSDN博客

Mybatis 的常见面试题_mybatis 列名循环_eaphy的博客-CSDN博客

Mybatis面试题(总结最全面的面试题!!!) - 知乎MyBatis(优点&缺点)&MyBatis使用详解! - 知乎 

Mybatis中属性名和字段名可不一致(使用resultType)_resulttype 属性名_吉士粉狗的博客-CSDN博客

MyBatis学习笔记:表字段名与实体类属性名不一致的解决方法_HelloWorld_EE的博客-CSDN博客https://www.cnblogs.com/qxhIndex/p/14137586.html

https://www.cnblogs.com/ubiquitousShare/p/12505815.html

Spring Boot——MyBatis配置带下划线命名的字段自动转换驼峰命名解决方案_@select 单个接口关闭下划线驼峰_Starzkg的博客-CSDN博客 SSM面试题5:MyBatis中当实体类中的属性名和表中的字段名不一样 ,怎么办 ?_ssm 表名和实体类 不一样_丨风语者丨的博客-CSDN博客Mybatis注解方式下处理实体类与数据库表列名不一致_mybatis表名与类名不一致注解_guohongyanghy的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值