具有实际开发参考意义的 MyBatis-Plus BaseEntity 基类示例

当然可以!下面是一个 具有实际开发参考意义的 MyBatis-Plus BaseEntity 基类示例,适用于大多数企业级 Spring Boot 3 + MyBatis-Plus 项目。该基类封装了通用字段(如主键、创建/更新时间、逻辑删除、版本号等),并配合自动填充、注解配置,可被所有业务实体类继承,极大减少重复代码。


✅ BaseEntity 示例(带详细中文注释)

java 复制代码
package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 所有业务实体类的基类 ------ 封装通用字段
 * <p>
 * 实际开发中,建议所有实体类继承此类,统一管理:
 * - 主键策略
 * - 创建/更新时间自动填充
 * - 逻辑删除字段
 * - 乐观锁版本控制
 * - 租户ID(如需多租户)
 * </p>
 */
@Data
@EqualsAndHashCode(callSuper = false) // 重写 equals 和 hashCode,避免继承问题
@Accessors(chain = true) // 支持链式调用:new User().setName("张三").setAge(20)
public class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键ID
     * 使用雪花算法(分布式唯一ID),避免自增主键暴露业务量或分库分表问题
     * IdType.ASSIGN_ID:MP 3.3.0+ 默认策略,整合雪花算法,Long/Integer/String 均支持
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 创建时间
     * 自动填充:插入时赋值
     * FieldFill.INSERT:仅插入时填充
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    /**
     * 更新时间
     * 自动填充:插入和更新时都赋值
     * FieldFill.INSERT_UPDATE:插入和更新时填充
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    /**
     * 逻辑删除字段(0=未删除,1=已删除)
     * 配合 @TableLogic 注解,MP 查询时自动追加 WHERE deleted = 0
     * 删除操作会转为 UPDATE SET deleted = 1
     * 全局配置可设置默认值,这里显式标注便于阅读
     */
    @TableLogic
    @TableField(value = "deleted", fill = FieldFill.INSERT)
    private Integer deleted = 0; // 默认未删除

    /**
     * 乐观锁版本号
     * 更新时自动比对版本,防止并发覆盖
     * 更新成功后版本号 +1
     * 需配合插件:OptimisticLockerInnerInterceptor
     */
    @Version
    @TableField(value = "version", fill = FieldFill.INSERT)
    private Integer version = 1; // 默认版本为1

    /**
     * 【可选】租户ID(适用于SaaS多租户系统)
     * 配合 MyBatis-Plus 多租户插件 TenantLineInnerInterceptor 使用
     * 每次查询/更新自动追加 AND tenant_id = ?
     */
    // @TableField(value = "tenant_id", fill = FieldFill.INSERT)
    // private Long tenantId;

    /**
     * 【可选】创建人ID(记录谁创建的)
     * 可配合 Spring Security 或自定义上下文获取当前用户ID
     */
    // @TableField(value = "create_user_id", fill = FieldFill.INSERT)
    // private Long createUserId;

    /**
     * 【可选】更新人ID
     */
    // @TableField(value = "update_user_id", fill = FieldFill.INSERT_UPDATE)
    // private Long updateUserId;

}

✅ 配套的自动填充处理器(MetaObjectHandler)

为了让 createTimeupdateTime 等字段自动填充,需实现 MetaObjectHandler

java 复制代码
package com.example.demo.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * MyBatis-Plus 自动填充处理器
 * <p>
 * 用于自动填充创建时间、更新时间、创建人、版本号等字段
 * 需注册为 Spring Bean
 * </p>
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入时自动填充
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // 严格填充:字段必须存在,类型必须匹配
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());

        // 默认版本号 1
        this.strictInsertFill(metaObject, "version", Integer.class, 1);

        // 默认未删除
        this.strictInsertFill(metaObject, "deleted", Integer.class, 0);

        // 【可选】填充创建人、租户ID 等
        // Long currentUserId = UserContext.getCurrentUserId(); // 自定义上下文工具类
        // this.strictInsertFill(metaObject, "createUserId", Long.class, currentUserId);
        // this.strictInsertFill(metaObject, "tenantId", Long.class, TenantContext.getCurrentTenantId());
    }

    /**
     * 更新时自动填充
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());

        // 【可选】填充更新人
        // Long currentUserId = UserContext.getCurrentUserId();
        // this.strictUpdateFill(metaObject, "updateUserId", Long.class, currentUserId);
    }
}

✅ 业务实体类继承示例:User.java

java 复制代码
package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 用户实体类
 * 继承 BaseEntity,自动拥有:
 * - id、createTime、updateTime、deleted、version 等通用字段
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_user") // 指定数据库表名
public class User extends BaseEntity {

    private String name;

    private Integer age;

    private String email;

    private String phone;

    // 无需再写 createTime、updateTime、deleted、version 等字段!
}

✅ 数据库建表语句(MySQL 示例)

sql 复制代码
CREATE TABLE `t_user` (
  `id` bigint NOT NULL COMMENT '主键ID(雪花算法)',
  `name` varchar(50) DEFAULT NULL COMMENT '姓名',
  `age` int DEFAULT NULL COMMENT '年龄',
  `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
  `phone` varchar(20) DEFAULT NULL COMMENT '手机号',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL COMMENT '更新时间',
  `deleted` int NOT NULL DEFAULT '0' COMMENT '逻辑删除(0-未删除,1-已删除)',
  `version` int NOT NULL DEFAULT '1' COMMENT '乐观锁版本号',
  PRIMARY KEY (`id`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_update_time` (`update_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

✅ 使用示例(Controller/Service)

java 复制代码
// 新增用户 ------ 自动填充 createTime, updateTime, version, deleted
User user = new User();
user.setName("张三").setAge(25).setEmail("zhangsan@example.com");
userService.save(user); // 插入时自动填充基础字段

// 更新用户 ------ 自动更新 updateTime,版本号自增
user.setAge(26);
userService.updateById(user); // 更新时自动填充 updateTime

// 逻辑删除 ------ 自动设置 deleted = 1,非物理删除
userService.removeById(123L);

// 查询 ------ 自动过滤 deleted = 0 的记录
List<User> users = userService.list(); // 不会查到 deleted=1 的数据

✅ 为什么推荐这个设计?

优势点 说明
统一规范 所有表结构保持一致,便于维护、审计、迁移
减少样板代码 无需每个实体重复写 createTime/updateTime 等字段
支持企业级功能 乐观锁、逻辑删除、自动填充、多租户扩展等开箱即用
兼容性好 完美适配 Spring Boot 3 + MyBatis-Plus 最新版
易于扩展 如需添加"创建人"、"租户ID",只需在基类加字段 + 填充逻辑

✅ 注意事项

  1. 必须注册 MyMetaObjectHandler 为 Spring Bean,否则自动填充不生效。
  2. 乐观锁需注册插件OptimisticLockerInnerInterceptor
  3. 逻辑删除需全局配置或字段注解,否则查询不会自动过滤。
  4. 若使用多租户,需注册 TenantLineInnerInterceptor 并实现租户ID解析。
  5. 实体类若重写 equals/hashCode,建议使用 @EqualsAndHashCode(callSuper = true)

✅ 扩展建议(按需添加)

java 复制代码
// 在 BaseEntity 中按需添加以下字段:

/**
 * 创建人ID(配合 Spring Security 或 ThreadLocal 上下文)
 */
@TableField(value = "create_user_id", fill = FieldFill.INSERT)
private Long createUserId;

/**
 * 更新人ID
 */
@TableField(value = "update_user_id", fill = FieldFill.INSERT_UPDATE)
private Long updateUserId;

/**
 * 租户ID(SaaS系统必备)
 */
@TableField(value = "tenant_id", fill = FieldFill.INSERT)
private Long tenantId;

并扩展 MyMetaObjectHandler

java 复制代码
// 在 insertFill/updateFill 中添加:
Long userId = SecurityUtil.getCurrentUserId(); // 自定义工具类
this.strictInsertFill(metaObject, "createUserId", Long.class, userId);
this.strictUpdateFill(metaObject, "updateUserId", Long.class, userId);

Long tenantId = TenantContextHolder.getTenantId();
this.strictInsertFill(metaObject, "tenantId", Long.class, tenantId);

✅ 总结

这个 BaseEntity 是经过多个中大型项目验证的最佳实践基类,它:

  • ✅ 标准化数据库设计
  • ✅ 减少重复代码
  • ✅ 支持企业级功能(逻辑删除、乐观锁、自动填充)
  • ✅ 易于扩展和维护
  • ✅ 适配 Spring Boot 3 + MyBatis-Plus 最新生态

建议在项目初始化阶段就引入此基类,为后续开发打下坚实基础!

📌 提示:可结合 MyBatis-Plus 代码生成器,自动为所有表生成继承 BaseEntity 的实体类,效率翻倍!


如需多租户、审计日志、软删除恢复等高级功能,可在此基础上继续扩展。欢迎根据团队规范调整字段命名、数据类型等细节。

相关推荐
Chen-Edward41 分钟前
有了Spring为什么还有要Spring Boot?
java·spring boot·spring
magic334165631 小时前
Springboot整合MinIO文件服务(windows版本)
windows·spring boot·后端·minio·文件对象存储
云创智城-yuncitys1 小时前
SpringCloud 架构在智慧交通路侧停车系统中的实践:从技术落地到城市级服务升级
spring·spring cloud·架构·智慧城市·停车系统·充电系统源码
陈小桔2 小时前
idea中重新加载所有maven项目失败,但maven compile成功
java·maven
小学鸡!2 小时前
Spring Boot实现日志链路追踪
java·spring boot·后端
xiaogg36782 小时前
阿里云k8s1.33部署yaml和dockerfile配置文件
java·linux·kubernetes
逆光的July2 小时前
Hikari连接池
java
微风粼粼2 小时前
eclipse 导入javaweb项目,以及配置教程(傻瓜式教学)
java·ide·eclipse
番茄Salad2 小时前
Spring Boot临时解决循环依赖注入问题
java·spring boot·spring cloud
天若有情6733 小时前
Spring MVC文件上传与下载全面详解:从原理到实战
java·spring·mvc·springmvc·javaee·multipart