关于Mybatis-plus的@TableFiled注解的自动注入功能产生的槽点

最近用Mybatis-plus比较多,这个框架带来的快速开发的效果也比较好,但是,由于技术架构的时间较长,开发团队的不断更新,导致程序设计及开发出现了问题,

注释:该部分代码分析版本来自于Mybatis-plus 3.4.0 版本不同可能有细微差异,仅供参考

(虽然我不觉得这部分基础代码会在版本迭代下进行较大的改动)

问题1:

create_time 字段从 因为项目组开发人员不断更新 历史实体类中createTime 默认的 Date类型 在新增的实体类中手中变成了 LocalDateTime 这本身没有什么问题,但是。。。

导致:

新实体类中 在 createTime 字段上 添加 @TableFiled(fill = INSERT) 产生自动注入失败 的问题

原因是:

new Date() 产生的数据是 CST 格式 无法放入 LocalDateTime

结果:

我们的 每个新的实体类 只要采用了 LocalDateTime 的字段设计 就只能用 setCreateTime(LocalDateTime.now()) 的方式来完成时间数据的注入

这就令人很是烦躁!!! 不过,也同样侧面说明了,虽然目前市面上提供的java工具很好用,但要完全兼容历史架构,需要对历史架构足够熟悉,否则,也会影响真实的开发效率

问题2

那createTime没办法偷懒了,我得想办法偷别的字段的懒 !!!要么多对不起程序员,然后就出问题了

这次bug十分意外,在插入createBy的时候,又出现了时间问题???

而且,这次排查的bug还让我学到了一些小东西

排查bug

其实这个bug排查的时间也不久,可以预见性知道一定是注入的问题,但一个决定性问题影响了我的思路

就是在我认知中 Mybatis-plus 应该是只对加了 @TableField(fill = FieldFill.INSERT)的注解进行添加的方法,但让我万万没想到的是,实际上不是这个样子的

翻阅一下Mybatis-plus的插入/更新源码

其实入参实体就是我们携带了 @TableField(fill = FieldFill.INSERT)所在的 实体类 大概可以理解为:

kotlin 复制代码
public class User{

    @TableId(type = IdType.ASSIGN_UUID)
    private String id;
    
    @TableField(fill = FieldFill.INSERT)
    private String name ;
}

这个样子,就是 可以理解为 MateObject 的 数据结构 包含了 这个实体类的,及相关的注解详情

主键生成策略这部分。和我关注这部分关联性不高,直接跳过

第一个全局的开启,默认是开启的 可以在实现了 MetaObjectHandler 接口的类下内重写这个方法 直接返回 false 即可关闭

第二个的话,比较神奇,是在启动的时候初始化 entity然后扫描到这个实体类中是否存在了 @TableField(fill = FieldFill.INSERT)注解,只要有一个存在,就为 true

(坑点就在这里)

最终的结果走进了判断, 触发了我心心念念的 metaObjectHandler.insertFill(metaObject)方法

但是metaObject中包含的是整个实体类! createTime也在其中啊!!直接把我的createTime给干掉了,报了个和问题1,一模一样的错误。。

原因

找到原因了,原来是@TableField(fill = FieldFill.INSERT) 在实体类中 只要有一个,就会渲染将整个实体类标注为开启自动填充(虽然没什么问题,但是我最开始是认为精细到字段的,不翻还真的不知道)

结果

为了项目稳定,不再引发其他连锁反应,我没敢动 这个Mybatis的自动插入代码

就是实现了 MetaObjectHandler 接口的类,并实现了 insertFill(MetaObject metaObject) 方法 的这个 处理器 其实有一个解决办法,就是我一定要将将所有包含createTime 的实体类在 insert前,触发一次setCreateTime(LocalDateTime.now) 然后再insertFill中做一个判空,就可以解决这个问题,这就属于约定大于配置了。

但,为了防止其他问题,就只能,用setCrateBy(Security.getUserName())setCreateTime(LocalDateTime.now) 来委屈我疲惫的大猪蹄子了。

好像是第一次在掘金上发布文章,东西不难,不过场景很少见(毕竟是历史开发人员和新开发人员思维上的冲突),不过,还是希望后续有人避免遇见像我这样的bug,祝:各位看博文的朋友们都能遇见百万并发的项目

相关推荐
wowocpp41 分钟前
spring boot Controller 和 RestController 的区别
java·spring boot·后端
后青春期的诗go1 小时前
基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(二)
开发语言·后端·rust·rocket框架
freellf1 小时前
go语言学习进阶
后端·学习·golang
全栈派森3 小时前
云存储最佳实践
后端·python·程序人生·flask
CircleMouse3 小时前
基于 RedisTemplate 的分页缓存设计
java·开发语言·后端·spring·缓存
獨枭4 小时前
使用 163 邮箱实现 Spring Boot 邮箱验证码登录
java·spring boot·后端
维基框架4 小时前
Spring Boot 封装 MinIO 工具
java·spring boot·后端
秋野酱4 小时前
基于javaweb的SpringBoot酒店管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
☞无能盖世♛逞何英雄☜4 小时前
Flask框架搭建
后端·python·flask
进击的雷神5 小时前
Perl语言深度考查:从文本处理到正则表达式的全面掌握
开发语言·后端·scala