🎼个人主页:【Y小夜】
😎作者简介:一位双非学校的大三学生,编程爱好者,
专注于基础和实战分享,欢迎私信咨询!
🎆入门专栏:🎇【MySQL,Java基础,Rust】
🎈热门专栏:🎊【Python,Javaweb,Springboot】
感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️
目录
🎈主要解决的问题
🎈优点
🎈业务开发
🎉实现步骤
🎉实战案例
在SpringBoot中,公共字段自动填充是为了解决在数据库操作中频繁设置一些通用字段(如创建时间、修改时间、创建人ID、修改人ID等)的问题。这些字段在多个表中都可能存在,且每次进行插入或更新操作时都需要a赋值,如果手动在每个业务方法中进行赋值操作,会导致代码冗余和繁琐。
🎈主要解决的问题
-
代码冗余:避免在每个业务方法中重复编写赋值逻辑,减少代码量。
-
维护困难:当公共字段的赋值逻辑需要变更时,只需修改一处即可,无需逐个修改业务方法。
-
提高开发效率:开发人员可以专注于业务逻辑的实现,而无需关心公共字段的赋值细节。
-
减少错误:自动填充可以减少因人为疏忽而导致的赋值错误。
🎈优点
-
简化代码结构:通过AOP(面向切面编程)和自定义注解等方式,将公共字段的赋值逻辑从业务方法中分离出来,使代码更加清晰和简洁。
-
提高可读性:业务方法不再包含与业务逻辑无关的赋值代码,更容易被理解和维护。
-
增强灵活性:可以根据不同的需求灵活地配置公共字段的赋值策略,如仅在插入时赋值、在插入和更新时都赋值等。
-
提升性能:虽然自动填充本身不会直接提升性能,但它可以减少开发人员在赋值逻辑上的思考和编码时间,从而间接提高开发效率。
🎈业务开发
提醒:本次是使用的基于mp的框架
🎉实现步骤
第一步:在实体类的属性上加入@TableField注解,指定自动填充的策略
第二步:按框架要求编写店数据对象处理器,在次类中统一为公共字段赋值,此类需要是实现MetaObjectHandle接口
🎉实战案例
这里以瑞吉外卖举例子
Employee:
java">package org.example.reggie.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;@Data
public class Employee implements Serializable {private static final long serialVersionUID = 1L;private Long id;private String username;private String name;private String password;private String phone;private String sex;private String idNumber;private Integer status;@TableField(fill = FieldFill.INSERT)//插入时填充字段private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)private Long updateUser;}
实现 MetaObjectHandler:
java">package org.example.reggie.common;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;/*** 元数据处理器,用于填充公共字段*/
@Component
public class MyMetaObjecthandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {metaObject.setValue("createTime", LocalDateTime.now());metaObject.setValue("updateTime", LocalDateTime.now());metaObject.setValue("createUser", BaseContext.getCurrentId());metaObject.setValue("updateUser", BaseContext.getCurrentId());}@Overridepublic void updateFill(MetaObject metaObject) {metaObject.setValue("updateTime", LocalDateTime.now());metaObject.setValue("updateUser", BaseContext.getCurrentId());}
}
提醒:这里BaseContext类是用了thread local实现的一个类,主要方法如下
BaseContext类
java">package org.example.reggie.common;/*** 机遇ThreadLocal封装工具类,用户保存和获取当前登入的用户id*/
public class BaseContext {private static final ThreadLocal<Long> threadLocal = new ThreadLocal<>();/*** 将id存入threadlocal* @param id*/public static void setCurrentId(Long id){threadLocal.set(id);}/*** 取出threadlocal中的id* @return*/public static Long getCurrentId(){return threadLocal.get();}
}
用户登录后,将userid存入threadlocal中,当需要时,利用静态方法取出