【MP-BUG】记录一次工作开发遇到的Mybatis-PLUS@TableName注解autoResultMap引起的BUG

首先@TableName是用在实体类上和数据的表做映射的注解

autoResultMap是当表中有json字段类型的时候,我们需要在@TableName注解加上这个属性,并且在实体属性上加上注解 @TableField(typeHandler = JacksonTypeHandler.class)。要不然查出来是null。

以上是前提。适用的MP版本是3.3.1。并且配置 map-underscore-to-camel-case: false

查询列表service
这里是查询的service代码。排除掉一些字段 进行调用MP的list方法进行查询。
在这里插入图片描述
这个是实体类部门字段。
在这里插入图片描述

这个是打印的SQL语句。 我们发现经过 @TableField注解的字段在使用AS进行重命名。 这里应该是为了使字段映射到实体类上。
然后我发现,这里查询出来的数据,实体类中经过 @TableField注解的字段并没有映射上数据
在这里插入图片描述
然后我发现,这里查询出来的数据,实体类中经过 @TableField注解的字段并没有映射上数据(实际的数据库里面该字段有值,并且SQL语句能正常查询出来)。

然后取消掉autoResultMap = true属性
发现查询SQL没变,字段能正常映射上了
在这里插入图片描述
=手动分割===============
这里没有看源码,以下部分都是猜想 = =。
当我们使用了@TableField(value = “article_id”)这个注解过后,我们调用MP本身的方法查询(通过我上图传class的方式指定字段或者select(SFunction<T, ?>… columns),而不是select * 或者select(String… columns)),的时候。会在SQL上加上AS进行重命名。所以这里会在映射的时候找到属性本身进行映射。这样就没有问题。
但是当我们在@TableName加上autoResultMap = true属性的时候,MP在进行映射的时候,找的就不是实体类属性本身了,而是去先找@TableField 找到了这个注解里面的value,有值的话就会去通过这上面的value进行映射。也就是说我们这里article_id(articleId)的映射值是article_id但是查的时候因为加了@TableField 所以查出来的是articleId。导致没有映射上。
后续我调用了MP的getById()方法。因为这个方法是直接select * 去查询(后续发现是加上autoResultMap = true属性是select * 。但是没加这个属性 就还是select 所有的字段名,并且配置了@TableField(“xxxx”)会重命名),那么查询出来的字段就是article_id。这个时候没有删除autoResultMap = true属性。发现也能够正常映射。说明这个时候是去找的@TableField(value = “article_id”)进行的映射。而不是 private String articleId;

=== 再分割一下====================
猜想毕竟只能是猜想。肯定不行。!但是我一直没下载下来源码,所以我这边就去官网看了一下这个属性的介绍
在这里插入图片描述
我们发现autoResultMap这个属性是自动构建了一个resultMap。也就是对于我们这里来说,如果我这里加上了这个属性。那么就相当于配置了一个这个。
在这里插入图片描述
那么也就是说在去映射的时候回去找article_id这个字段取映射到articleId这个属性。但是因为查询的时候又重命名了,所以就找不到article_id这个字段,导致查出来的东西没值。

后面发现对于autoResultMap这个属性,MP针对getById这个方法都做了优化,有这个属性的时候是select * 没这个熟悉是调用select 字段吗 AS 重命名。 但是针对上述这种情况不知道为什么没有优化。针对我当前这个版本,也不知道后续版本有没有优化这个问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值