MyBatis与MyBatis-Plus:字段主动填充的两种实现方式
目次1. 使用 MyBatis 拦截器实现字段主动填充
2. 使用 MyBatis-Plus 实现字段主动填充
1. 使用 MyBatis 拦截器实现字段主动填充
实现步调
[*] 创建拦截器 实现 MyBatis 的 Interceptor 接口,通过拦截 MyBatis 实行的 SQL 操作来主动填充公共字段
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class CommonFieldInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
if (invocation.getArgs().length > 1) {
Object parameter = invocation.getArgs();
if (parameter instanceof BaseEntity) {
BaseEntity entity = (BaseEntity) parameter;
if (isInsertOperation(invocation)) {
entity.setCreateTime(new Date());
entity.setUpdateTime(new Date());
} else if (isUpdateOperation(invocation)) {
entity.setUpdateTime(new Date());
}
}
}
return invocation.proceed();
}
private boolean isInsertOperation(Invocation invocation) {
String methodName = ((MappedStatement) invocation.getArgs()).getId();
return methodName.contains("insert");
}
private boolean isUpdateOperation(Invocation invocation) {
String methodName = ((MappedStatement) invocation.getArgs()).getId();
return methodName.contains("update");
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 可选:设置属性
}
}
[*] 定义基础实体类 创建一个基础实体类 BaseEntity,包含需要主动填充的公共字段,全部需要主动填充的实体类都应继承该类
public class BaseEntity {
private Date createTime;
private Date updateTime;
// getters and setters
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
[*] 配置拦截器 在 MyBatis 配置文件中注册拦截器
<plugins>
<plugin interceptor="com.example.mybatis.interceptor.CommonFieldInterceptor"/>
</plugins>
[*] 使用示例 创建一个继承 BaseEntity 的实体类,并在 Mapper 中使用该实体类举行数据库操作
public class User extends BaseEntity {
private Long id;
private String name;
// getters and setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} @Mapper
public interface UserMapper {
@Insert("INSERT INTO user (name, create_time, update_time) VALUES (#{name}, #{createTime}, #{updateTime})")
void insert(User user);
@Update("UPDATE user SET name = #{name}, update_time = #{updateTime} WHERE id = #{id}")
void update(User user);
}
2. 使用 MyBatis-Plus 实现字段主动填充
实现步调
[*] 定义实体类 在实体类中,使用 @TableField 注解来标记需要主动填充的字段,并指定填充策略
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Integer id;
private String username;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createdAt;// 创建时自动填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updatedAt;// 创建和更新时自动填充
}
[*] 实现 MetaObjectHandler 创建一个类实现 MetaObjectHandler 接口,并重写 insertFill 和 updateFill 方法,定义插入和更新时的填充逻辑。
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createdAt", LocalDateTime::now, LocalDateTime.class);
this.strictInsertFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
}
}
[*] 配置主动填充处理器 确保 MyMetaObjectHandler 类被 Spring 管理,可以通过 @Component 或 @Bean 注解来实现。
[*] 使用示例 创建一个继承自 BaseMapper 的 Mapper 接口
@Mapper
public interface UserMapper extends BaseMapper<User> {
} 测试代码
@Component
public class MyTestRunner implements CommandLineRunner {
@Autowired
private UserMapper userMapper;
@Override
public void run(String... args) throws Exception {
// 测试插入时自动填充
User user = new User();
user.setUsername("John Doe");
userMapper.insert(user);
System.out.println("Inserted user: " + user);
// 测试更新时自动填充
user.setUsername("Jane Doe");
userMapper.updateById(user);
System.out.println("Updated user: " + user);
}
}
两种方式的对比
[*] MyBatis 拦截器方式
[*] 优点:灵活性高,可以自定义复杂的填充逻辑,适用于复杂的业务场景。
[*] 缺点:实现相对复杂,需要编写较多代码,且需要手动添加注解。
[*] MyBatis-Plus 方式
[*] 优点:使用简单,代码量少,开箱即用,与 MyBatis-Plus 无缝集成。
[*] 缺点:填充逻辑相对固定,扩展性较差。
选择建议
[*] 假如需要实现简单的主动填充功能,如创建时间和更新时间的主动填充,推荐使用 MyBatis-Plus 方式。
[*] 假如有复杂的业务逻辑,需要自定义填充逻辑,推荐使用 MyBatis 拦截器方式。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]