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)存在冲突。没有去看源码,但大概现象如此。

相关推荐
麻瓜code5 小时前
双写一致性:为什么是“删缓存“,而不是“改缓存“
java·缓存·mybatis
郭小李1 天前
mybatis 动态 sql
java·sql·mybatis
知守观1 天前
技术考古:iBATIS 2.3.4 时代的持久层,是如何用 Map 玩转 307 个存储过程的?
java·后端·mybatis
captain3761 天前
MyBatis Plus(1)
java·服务器·mybatis
代码不停1 天前
MyBatis进阶
spring boot·mybatis
captain3762 天前
MyBatis(入门5)其他查询操作
java·数据库·spring boot·mybatis
captain3762 天前
MyBatis(进阶1)
mybatis
郭小李2 天前
mybatis的 Mapper.xml语法
xml·java·mybatis
m0_639906942 天前
MyBatis 实现分页查询|逻辑分页、物理分页、PageHelper 原理
mybatis
captain3763 天前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis