MyBatis与MyBatis-Plus:字段主动填充的两种实现方式

打印 上一主题 下一主题

主题 1784|帖子 1784|积分 5352

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目次
1. 使用 MyBatis 拦截器实现字段主动填充
2. 使用 MyBatis-Plus 实现字段主动填充


1. 使用 MyBatis 拦截器实现字段主动填充

实现步调


  • 创建拦截器 实现 MyBatis 的 Interceptor 接口,通过拦截 MyBatis 实行的 SQL 操作来主动填充公共字段
    1. @Intercepts({
    2.     @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
    3. })
    4. public class CommonFieldInterceptor implements Interceptor {
    5.     @Override
    6.     public Object intercept(Invocation invocation) throws Throwable {
    7.         if (invocation.getArgs().length > 1) {
    8.             Object parameter = invocation.getArgs()[1];
    9.             if (parameter instanceof BaseEntity) {
    10.                 BaseEntity entity = (BaseEntity) parameter;
    11.                 if (isInsertOperation(invocation)) {
    12.                     entity.setCreateTime(new Date());
    13.                     entity.setUpdateTime(new Date());
    14.                 } else if (isUpdateOperation(invocation)) {
    15.                     entity.setUpdateTime(new Date());
    16.                 }
    17.             }
    18.         }
    19.         return invocation.proceed();
    20.     }
    21.     private boolean isInsertOperation(Invocation invocation) {
    22.         String methodName = ((MappedStatement) invocation.getArgs()[0]).getId();
    23.         return methodName.contains("insert");
    24.     }
    25.     private boolean isUpdateOperation(Invocation invocation) {
    26.         String methodName = ((MappedStatement) invocation.getArgs()[0]).getId();
    27.         return methodName.contains("update");
    28.     }
    29.     @Override
    30.     public Object plugin(Object target) {
    31.         return Plugin.wrap(target, this);
    32.     }
    33.     @Override
    34.     public void setProperties(Properties properties) {
    35.         // 可选:设置属性
    36.     }
    37. }
    复制代码
  • 定义基础实体类 创建一个基础实体类 BaseEntity,包含需要主动填充的公共字段,全部需要主动填充的实体类都应继承该类
    1. public class BaseEntity {
    2.     private Date createTime;
    3.     private Date updateTime;
    4.     // getters and setters
    5.     public Date getCreateTime() {
    6.         return createTime;
    7.     }
    8.     public void setCreateTime(Date createTime) {
    9.         this.createTime = createTime;
    10.     }
    11.     public Date getUpdateTime() {
    12.         return updateTime;
    13.     }
    14.     public void setUpdateTime(Date updateTime) {
    15.         this.updateTime = updateTime;
    16.     }
    17. }
    复制代码
  • 配置拦截器 在 MyBatis 配置文件中注册拦截器
    1. <plugins>
    2.     <plugin interceptor="com.example.mybatis.interceptor.CommonFieldInterceptor"/>
    3. </plugins>
    复制代码
  • 使用示例 创建一个继承 BaseEntity 的实体类,并在 Mapper 中使用该实体类举行数据库操作
    1. public class User extends BaseEntity {
    2.     private Long id;
    3.     private String name;
    4.     // getters and setters
    5.     public Long getId() {
    6.         return id;
    7.     }
    8.     public void setId(Long id) {
    9.         this.id = id;
    10.     }
    11.     public String getName() {
    12.         return name;
    13.     }
    14.     public void setName(String name) {
    15.         this.name = name;
    16.     }
    17. }
    复制代码
    1. @Mapper
    2. public interface UserMapper {
    3.     @Insert("INSERT INTO user (name, create_time, update_time) VALUES (#{name}, #{createTime}, #{updateTime})")
    4.     void insert(User user);
    5.     @Update("UPDATE user SET name = #{name}, update_time = #{updateTime} WHERE id = #{id}")
    6.     void update(User user);
    7. }
    复制代码
2. 使用 MyBatis-Plus 实现字段主动填充

实现步调


  • 定义实体类 在实体类中,使用 @TableField 注解来标记需要主动填充的字段,并指定填充策略
    1. @Data
    2. @TableName("user")
    3. public class User {
    4.     @TableId(type = IdType.AUTO)
    5.     private Integer id;
    6.     private String username;
    7.     @TableField(fill = FieldFill.INSERT)
    8.     private LocalDateTime createdAt;  // 创建时自动填充
    9.     @TableField(fill = FieldFill.INSERT_UPDATE)
    10.     private LocalDateTime updatedAt;  // 创建和更新时自动填充
    11. }
    复制代码
  • 实现 MetaObjectHandler 创建一个类实现 MetaObjectHandler 接口,并重写 insertFill 和 updateFill 方法,定义插入和更新时的填充逻辑。
    1. @Component
    2. public class MyMetaObjectHandler implements MetaObjectHandler {
    3.     @Override
    4.     public void insertFill(MetaObject metaObject) {
    5.         this.strictInsertFill(metaObject, "createdAt", LocalDateTime::now, LocalDateTime.class);
    6.         this.strictInsertFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
    7.     }
    8.     @Override
    9.     public void updateFill(MetaObject metaObject) {
    10.         this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
    11.     }
    12. }
    复制代码
  • 配置主动填充处理器 确保 MyMetaObjectHandler 类被 Spring 管理,可以通过 @Component 或 @Bean 注解来实现。
  • 使用示例 创建一个继承自 BaseMapper 的 Mapper 接口
    1. @Mapper
    2. public interface UserMapper extends BaseMapper<User> {
    3. }
    复制代码
    测试代码
    1. @Component
    2. public class MyTestRunner implements CommandLineRunner {
    3.     @Autowired
    4.     private UserMapper userMapper;
    5.     @Override
    6.     public void run(String... args) throws Exception {
    7.         // 测试插入时自动填充
    8.         User user = new User();
    9.         user.setUsername("John Doe");
    10.         userMapper.insert(user);
    11.         System.out.println("Inserted user: " + user);
    12.         // 测试更新时自动填充
    13.         user.setUsername("Jane Doe");
    14.         userMapper.updateById(user);
    15.         System.out.println("Updated user: " + user);
    16.     }
    17. }
    复制代码
两种方式的对比



  • MyBatis 拦截器方式

    • 优点:灵活性高,可以自定义复杂的填充逻辑,适用于复杂的业务场景。
    • 缺点:实现相对复杂,需要编写较多代码,且需要手动添加注解。

  • MyBatis-Plus 方式

    • 优点:使用简单,代码量少,开箱即用,与 MyBatis-Plus 无缝集成。
    • 缺点:填充逻辑相对固定,扩展性较差。

选择建议



  • 假如需要实现简单的主动填充功能,如创建时间和更新时间的主动填充,推荐使用 MyBatis-Plus 方式
  • 假如有复杂的业务逻辑,需要自定义填充逻辑,推荐使用 MyBatis 拦截器方式

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莫张周刘王

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表