MyBatis-Plus MetaObjectHandler的几个坑(主要是id字段)

1.背景

主要是要实现一个id字段的自增长,不依赖数据库的能力(已避免后续换库的问题)。姑且使用redis作为表的id分配器,因此使用MyBatis-Plus MetaObjectHandler对每个insert的id进行分配。

2.实施过程

以下是实现过程

1.实现MetaObjectHandler,重写insertFill,设置id

2.Configuration中实例化MetaObjectHandler

java 复制代码
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
	@Override
	public void insertFill(MetaObject metaObject) {
		Long id = getIdFromRedis(); //redis取id
		this.setFieldValByName("id", id, metaObject); //给id字段设置取得的主键值
	}
	@Override
	public void updateFill(MetaObject metaObject) {
		//其他操作
	}
}
//Configuration中获取MetaObjectHandler 
@Configuration(proxyBeanMethods = false)
public class MybatisAutoConfiguration implements WebMvcConfigurer {
	@Bean
	public MybatisPlusMetaObjectHandler mybatisPlusMetaObjectHandler() {
		return new MybatisPlusMetaObjectHandler();
	}
}

3.使用mybatis-plus的mapper内的save或者saveBatch方法

*4.需要注意的是对应实体类需要加上insert fill注解

java 复制代码
@Data
@TableName("TEST")
public class Test {
	@TableField(fill= FieldFill.INSERT)
	private Long id;
	private String fieldTest;
}

3.出现的问题

按上述方式实现后出现没有进入

insertFill的情况,

后来发现实体类只在id字段上加@TableField(fill= FieldFill.INSERT)是不会进insertFill的

因此尝试

java 复制代码
@Data
@TableName("TEST")
public class Test {
	@TableField(fill= FieldFill.INSERT)
	private Long id;
	@TableField(fill= FieldFill.INSERT) 
	private String fieldTest;
}

在另一个字段上加上@TableField(fill= FieldFill.INSERT)

然后成功进入了insertFill,也对id进行了赋值,但是最后生成的sql
居然没有id字段
居然没有id字段
居然没有id字段

是的,明明都已经走了对id的赋值,但生产的sql就是没有id字段赋值

4.最终解决

java 复制代码
@Data
@TableName("TEST")
public class Test {
	@TableId(type = IdType.INPUT)
	@TableField(fill= FieldFill.INSERT)
	private Long id;
	@TableField(fill= FieldFill.INSERT) 
	private String fieldTest;
}

最后是在id上加上@TableId(type = IdType.INPUT)使id字段的type是input,才成功实现了id从redis取这个功能

5.反思

然后我又尝试了以下代码

java 复制代码
@Data
@TableName("TEST")
public class Test {
	@TableId(type = IdType.INPUT)
	@TableField(fill= FieldFill.INSERT)
	private Long id;
	//@TableField(fill= FieldFill.INSERT) 
	private String fieldTest;
}

把其他字段上的@TableField(fill= FieldFill.INSERT) 去了 。。。然后又不会进入insertFill了

目测mybatis-plus源码的判断是,先判断是否存在非id字段需要走@TableField(fill= FieldFill.INSERT),才会进入insertFill,

然后判断设置填充的字段是否是id,且id有没有配置自定义Input

6.结论

本质上是id字段是mybatis-plus中的保留字段,一般需要配置@TableId,然后@TableId和@TableField(fill= FieldFill.INSERT)存在冲突。没有去看源码,但大概现象如此。

相关推荐
程序员JerrySUN14 小时前
Jetson Edge AI 实战01:Nano、Xavier、Orin 怎么选?Jetson 硬件选型详解【视频讲解】
java·数据库·redis·安全·mybatis
linmengmeng_131417 小时前
【总结】MyBatis-Plus批量插入与清表的正确姿势
java·spring boot·mysql·mybatis
vx_BS813301 天前
【项目编号:project51381】Spring Boot 婚纱摄影管理系统:套餐预约、在线咨询、支付与客片展示的一站式业务实现
java·spring boot·eclipse·tomcat·mybatis
jaysee-sjc2 天前
【苍穹外卖】Day01:从零认识企业级项目开发
java·开发语言·数据库·mysql·spring·intellij-idea·mybatis
程序猿乐锅2 天前
【黑马点评 | 第二篇】Redis 缓存更新策略与商铺缓存实现
java·网络·redis·spring·mybatis
萧瑟余晖2 天前
MyBatis 核心原理详解
架构·mybatis
MZA6662 天前
实战:基于 XXL-JOB + 策略模式 + Nacos 配置化的 CSV 导出任务系统设计
java·spring boot·mybatis
干到60岁退休的码农5 天前
15.创建获取用户接口与JWT认证器
java·spring boot·mybatis
干到60岁退休的码农5 天前
16.过滤器中处理异常响应返回
java·spring boot·mybatis
敲代码的嘎仔6 天前
互动问答系统实战:两级评论模型、ES 搜索集成、Caffeine 多级缓存全记录
java·开发语言·数据库·elasticsearch·缓存·mybatis·高并发