关于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,祝:各位看博文的朋友们都能遇见百万并发的项目

相关推荐
飘尘2 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
浏览器工程师3 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
行者全栈架构师3 小时前
Maven dependency:tree 的 8 个高级用法
java·后端
Chenyiax3 小时前
从一次请求看懂 OkHttp:架构、调度与连接管理
后端
爱勇宝4 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
AskHarries4 小时前
工具失败时怎么办:重试、回滚、人工确认和风险提示
后端·程序员
苏三说技术5 小时前
Claude Code从失控到起飞,只用了这些技巧
后端
长栎6 小时前
写 for 循环写了十年,你却从没用过迭代器模式最狠的那一面
后端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端
用户559822481227 小时前
Docker Compose Down 导致容器数据误删——ext4 日志恢复全记录
后端