Springboot/Springcloud为所有实体类创建一个共同的父类
一、需求
在设计数据库的时候每条数据基本上包含这么几个字段:主键ID,状态、创建者、创建时间、修改者、修改时间、是否逻辑删除......
每个实体类都包含这么几个相同的的字段的话显得有点冗余,操作数据也不方便,所以新建个所有实体类的父类来专门处理这些相同的字段就显得非常必要,这样每个实体类继承它就可以了不用每个都包含这些相同的字段了。
二、例子
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; import java.util.Date; import org.springframework.format.annotation.DateTimeFormat; public class BaseEntity implements Serializable { @JsonSerialize( using = ToStringSerializer.class ) @ApiModelProperty("主键id") @TableId( value = "id", type = IdType.ASSIGN_ID ) private Long id; @JsonSerialize( using = ToStringSerializer.class ) @ApiModelProperty("创建人") @TableField( fill = FieldFill.INSERT ) private Long createUser; @DateTimeFormat( pattern = "yyyy-MM-dd HH:mm:ss" ) @JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss" ) @ApiModelProperty("创建时间") @TableField( fill = FieldFill.INSERT ) private Date createTime; @JsonSerialize( using = ToStringSerializer.class ) @ApiModelProperty("更新人") @TableField( fill = FieldFill.UPDATE ) private Long updateUser; @DateTimeFormat( pattern = "yyyy-MM-dd HH:mm:ss" ) @JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss" ) @ApiModelProperty("更新时间") @TableField( fill = FieldFill.UPDATE ) private Date updateTime; @ApiModelProperty("业务状态") private Integer status; @TableLogic @ApiModelProperty("是否已删除") private Integer isDeleted; public BaseEntity() { } public Long getId() { return this.id; } public Long getCreateUser() { return this.createUser; } public Date getCreateTime() { return this.createTime; } public Long getUpdateUser() { return this.updateUser; } public Date getUpdateTime() { return this.updateTime; } public Integer getStatus() { return this.status; } public Integer getIsDeleted() { return this.isDeleted; } public void setId(final Long id) { this.id = id; } public void setCreateUser(final Long createUser) { this.createUser = createUser; } @JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss" ) public void setCreateTime(final Date createTime) { this.createTime = createTime; } public void setUpdateUser(final Long updateUser) { this.updateUser = updateUser; } @JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss" ) public void setUpdateTime(final Date updateTime) { this.updateTime = updateTime; } public void setStatus(final Integer status) { this.status = status; } public void setIsDeleted(final Integer isDeleted) { this.isDeleted = isDeleted; } public String toString() { return "BaseEntity(id=" + this.getId() + ", createUser=" + this.getCreateUser() + ", createTime=" + this.getCreateTime() + ", updateUser=" + this.getUpdateUser() + ", updateTime=" + this.getUpdateTime() + ", status=" + this.getStatus() + ", isDeleted=" + this.getIsDeleted() + ")"; }
三、里面使用的一些注解说明 根据自己的需要和情况使用,不用都可以
1.@JsonSerialize
来自于依赖jackjson,包:import com.fasterxml.jackson.databind.annotation.JsonSerialize;
作用:自定义字段的序列化
常用的有两个属性:
using 这个字段不为空的时候的自定义序列化
nullsUsing 这个字段为空时的自定义序列化
上面@JsonSerialize(using = ToStringSerializer.class)中的ToStringSerializer是我自定义的序列化方法,长的很,就不拿出来了自定义序列化方法、比如状态字段:
@JsonSerialize(nullsUsing = ToStatusSerializer.class)放在status字段上时就表示序列化的时候当status为空时会序列化成 状态异常
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.util.Date; //1.先继承JsonSerializer public class ToStatusSerializer extends JsonSerializer<Date> { //2.重写它的serialize方法 @Override public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { //3.自定义处理方式 jsonGenerator.writeString("状态异常"); } }
2.@TableI
常用的有两个属性:
value = "id", id是数据库字段的名称
type = IdType.ASSIGN_ID
IdType有如下这么几个值:
3.@ApiModelProperty("创建时间")
swagger的注解,一般用于给入参属性添加说明时使用,常用value属性:
value:字段说明
name:重写属性名字
dataType:重写属性类型
required:是否必填(true为必填)
example:举例说明
hidden:隐藏(true为隐藏)
4.@TableField(fill = FieldFill.INSERT)
一般用来处理实体类变量名字和数据库字段名字不一致问题的,即用来重命名的,如下重命名为aabbccdd
@TableField(value= "aabbccdd") 表示当前属性不是数据库的字段
@TableField(exist = false) 表示当前属性不是数据库的字段
这里fill是用来操作数据库的时候自动填充值的,FieldFill.INSERT就表示插入这条数据的时候该字段自动填充,
FieldFill.UPDATE就表示更新这条数据的时候该字段会自动填充,不用传值进去。
自动填充需要自定义方法并且实现MetaObjectHandler接口,如下所示 :
其中个别参数方法说明:
AuthUtil 获取当前登录的用户信息,可以从session中拿、用oauth2的也可以解析token得到当前登录用户信息,主要是为了拿到当前登录用户的ID,我自定义的长的很,就不拿出来了
ADMINISTRATOR_ID = 1123338824442275789 系统超级管理员的主键id,没有获取到当前登录用户信息的时候就默认用这个
Func.isEmpty() 自定义的判断对象是否为空的方法,也可以用官方提供的ObjectUtils.isEmpty()代替,实在不行用==判断去
@Configuration public class BtkscMetaObjectHandler implements MetaObjectHandler {private static final String CREATE_USER = "createUser"; private static final String UPDATE_USER = "updateUser"; private static final String IS_DELETED = "isDeleted"; private static final String CREATE_TIME = "createTime"; private static final String UPDATE_TIME = "updateTime"; private static final Long ADMINISTRATOR_ID = 1123338824442275789L; public MyMetaObjectHandler() { } public void insertFill(MetaObject metaObject) { if (metaObject.hasSetter("createUser")) { this.strictInsertFill(metaObject, "createUser", Long.class, Func.isEmpty(AuthUtil.getUser()) ? ADMINISTRATOR_ID : AuthUtil.getUser().getUserId()); } if (metaObject.hasSetter("createTime")) { this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); } } public void updateFill(MetaObject metaObject) { if (metaObject.hasSetter("updateUser")) { this.setFieldValByName("updateUser", Func.isEmpty(AuthUtil.getUser()) ? ADMINISTRATOR_ID : AuthUtil.getUser().getUserId(), metaObject); } if (metaObject.hasSetter("updateTime")) { this.setFieldValByName("updateTime", new Date(), metaObject); } } }
5.@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")和 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
用在日期类型上用来格式化日期的没啥好说的。
需要注意在字段上用了这个注解的时候相应字段的set方法上也需要加@JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss")
6.@TableLogic
逻辑删除注解,在字段上加上这个注解再执行BaseMapper的删除方法时,删除方法就会变成修改
@TableLogic注解参数
value = "" 默认的原值
delval = "" 删除后的值
@TableLogic(value="原来的值",delval="修改后的值")