当然可以!下面是一个 具有实际开发参考意义的 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)
为了让 createTime
、updateTime
等字段自动填充,需实现 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",只需在基类加字段 + 填充逻辑 |
✅ 注意事项
- 必须注册
MyMetaObjectHandler
为 Spring Bean,否则自动填充不生效。 - 乐观锁需注册插件 :
OptimisticLockerInnerInterceptor
- 逻辑删除需全局配置或字段注解,否则查询不会自动过滤。
- 若使用多租户,需注册
TenantLineInnerInterceptor
并实现租户ID解析。 - 实体类若重写
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
的实体类,效率翻倍!
如需多租户、审计日志、软删除恢复等高级功能,可在此基础上继续扩展。欢迎根据团队规范调整字段命名、数据类型等细节。