Loading... # **SpringBoot集成MyBatis-Plus字段自动填充方案** **💡 核心目标:通过元对象处理器实现字段自动化填充(如创建时间、更新时间、操作人)** --- ## **一、方案原理与适用场景** ### **1.1 原理解析** MyBatis-Plus通过 `MetaObjectHandler`接口实现字段填充,开发者只需: - **标注填充字段**:使用 `@TableField(fill = FieldFill.XXX)`注解 - **实现填充逻辑**:重写 `insertFill()`和 `updateFill()`方法 **适用场景**: - 审计字段(`create_time`、`update_time`) - 逻辑删除标记(`is_deleted`) - 操作人追踪(`operator_id`) --- ## **二、实现步骤详解** ### **步骤1:添加Maven依赖** ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> <!--截至2023年10月的最新稳定版--> </dependency> ``` **关键点**:确保版本≥3.3.0(支持Lambda表达式填充) --- ### **步骤2:实体类字段标注** ```java public class User { @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; @TableField(fill = FieldFill.INSERT) private String createBy; } ``` **参数说明**: - `FieldFill.INSERT`:仅插入时填充 - `FieldFill.UPDATE`:仅更新时填充 - `FieldFill.INSERT_UPDATE`:插入和更新时均填充 --- ### **步骤3:实现MetaObjectHandler接口** ```java @Component public class AutoFillHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); this.strictInsertFill(metaObject, "createBy", String.class, getCurrentUser()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); } private String getCurrentUser() { // 从Spring Security上下文获取当前用户(示例) return SecurityContextHolder.getContext().getAuthentication().getName(); } } ``` **代码解析**: - `strictInsertFill()`:类型严格的插入填充(避免字段类型不匹配) - `SecurityContextHolder`:结合Spring Security获取操作用户信息 --- ### **步骤4:启用MyBatis-Plus配置** ```yaml # application.yml mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 可选:查看SQL日志 global-config: db-config: logic-delete-field: isDeleted # 逻辑删除字段(如有需要) ``` --- ## **三、核心配置对照表** | **组件** | **作用** | **注意事项** | | --------------------- | ---------------------- | -------------------------------------- | | `@TableField` | 标注需要自动填充的字段 | 字段名必须与数据库列名一致 | | `MetaObjectHandler` | 实现字段填充逻辑 | 必须标注 `@Component`注入Spring容器 | | `strictInsertFill` | 类型安全的插入填充方法 | 参数顺序:MetaObject, 字段名, 类型, 值 | | `strictUpdateFill` | 类型安全的更新填充方法 | 需避免重复填充已有值的字段 | --- ## **四、工作流程图解** ```mermaid graph TD A[执行insert/update操作] --> B[MyBatis-Plus拦截SQL] B --> C{检查@TableField注解} C -->|存在填充标记| D[调用MetaObjectHandler对应方法] D --> E[填充预设值到实体对象] E --> F[生成最终SQL语句] ``` --- ## **五、高级技巧与避坑指南** ### **5.1 动态值填充** ```java // 获取动态数据(如当前用户ID) this.strictInsertFill(metaObject, "createBy", String.class, UserContext.getCurrentUserId()); ``` **适用场景**:多租户系统、操作日志记录 ### **5.2 覆盖已有值** ```java // 使用setFieldValByName强制覆盖 this.setFieldValByName("updateTime", new Date(), metaObject); ``` **注意**:慎用!可能导致数据不一致 ### **5.3 多字段联合填充** ```java // 同时填充创建时间和IP地址 this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); this.strictInsertFill(metaObject, "createIp", String.class, RequestUtils.getClientIP()); ``` --- ## **六、常见问题排查** ### **6.1 字段未自动填充** - **检查点1**:实体类字段是否添加 `@TableField(fill=...)` - **检查点2**:`MetaObjectHandler`是否被Spring管理(添加 `@Component`) - **检查点3**:字段名称是否与数据库列名一致(驼峰转下划线自动处理) ### **6.2 填充值不符合预期** ```java // 调试断点位置 @Override public void insertFill(MetaObject metaObject) { log.debug("进入insertFill方法"); // 添加日志观察触发情况 } ``` --- ## **七、最佳实践建议** 1. **隔离业务逻辑**:不要在 `MetaObjectHandler`中编写复杂业务代码 2. **单元测试覆盖**: ```java @SpringBootTest public class AutoFillTest { @Autowired private UserMapper userMapper; @Test void testInsertFill() { User user = new User(); userMapper.insert(user); // 验证createTime是否自动填充 } } ``` 3. **版本兼容性**:MyBatis-Plus ≥3.3.0推荐使用 `strictFill`方法 --- ## **八、总结** 通过 `@TableField`+`MetaObjectHandler`组合,可高效实现**审计字段、操作追踪、默认值设置**等场景的自动化处理。关键注意点: 1. **红颜色提醒**:必须确保 `MetaObjectHandler`实现类被Spring容器扫描到 2. **红颜色提醒**:使用 `strictInsertFill/strictUpdateFill`避免类型转换错误 3. 结合AOP或ThreadLocal实现动态数据(如用户信息)传递 **🎯 生产环境建议**:对填充逻辑添加单元测试,并监控关键字段的填充完整性。 最后修改:2025 年 04 月 04 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏