具有实际开发参考意义的 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 的实体类,效率翻倍!


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

相关推荐
whltaoin2 小时前
SpringCloud 项目阶段十:kafka实现双端信息同步以及ElasticSearch容器搭建示例
elasticsearch·spring cloud·kafka
神龙斗士2402 小时前
Java 数组的定义与使用
java·开发语言·数据结构·算法
计算机学姐2 小时前
基于微信小程序的扶贫助农系统【2026最新】
java·vue.js·spring boot·mysql·微信小程序·小程序·mybatis
白露与泡影2 小时前
2025互联网大厂高频Java面试真题解析
java·开发语言·面试
forever銳2 小时前
java中如何保证接口幂等性
java·后端
柯南二号2 小时前
【Java后端】MyBatis 和 MyBatis-Plus (MP) 的区别
java·数据库·tomcat
C++chaofan2 小时前
游标查询在对话历史场景下的独特优势
java·前端·javascript·数据库·spring boot
匿名4592 小时前
Lombok注解使用无效的情况(未能获得后端数据)
java·开发语言
小蒜学长2 小时前
springboot房地产销售管理系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端