实体Entity
Entity是实体类,和数据库的表结构对应。
SoFast框架中Entity由代码生成器自动生成,开发人员可基于定制需求进行修改。
Entity的规范
Entity类文件解耦合
Entity类建议放到feign sdk中,然后通过maven进行依赖,不建议将Entity类直接放在具体服务中。
在微服务架构中,一般会存在服务之间的调用,此时被调用服务的返回值实体类需要调用方进行解析,如果放在feign sdk中,调用方可直接使用,非常方便,即可feign接口修改,也只需升级maven中的依赖即可。
当然,如果该服务没有任何外部调用,那sdk是非必须的,将Entity类直接放入服务中也可以。
Entity主键
在SoFast框架中,主键id默认是使用的Mysql自增主键,因此在Entity类中id字段需要追加@TableId
注解,如下所示,注解@TableId
的type属性需要指定成IdType.AUTO
,否则不会使用自增策略。
@ApiModelProperty(value = "主键")
@JsonFormat(shape = JsonFormat.Shape.STRING)
@TableId(value = "id", type = IdType.AUTO)
private Long id;
主键过大问题
当Entity的id值过大后,通常为超过2的53次方(9007199254740992),传递到前端页面后,会出现精度丢失的问题。
根本原因是因为js number类型的最大安全值问题。
解决方案:
增加@JsonFormat
注解,将传递给前端的类型变成字符串。
@JsonFormat(shape = JsonFormat.Shape.STRING)
这种方案只是修改传递的json类型,并不需要修改Entity中的id类型和数据库的类型。
如果想要使用雪花算法或用户自定义主键,可通过修改@TableId注解实现。
// 使用雪花算法生成主键(数值或字符串类型)
@TableId(value = "id", type = IdType.ASSIGN_ID)
// 使用UUID生成主键(字符串类型,且不带"-")
@TableId(value = "id", type = IdType.ASSIGN_UUID)
// 开发人员自己生成主键
@TableId(value = "id", type = IdType.INPUT)
自动填充
在数据库插入或更新时,对于一些特定字段往往需要填充固定的信息,如创建者、创建时间、更新者、更新时间等。在SoFast中可以通过注解开启自动填充功能。
@ApiModelProperty(value = "创建者")
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@ApiModelProperty(value = "更新者")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
@ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
FieldFill.INSERT 只在inset时自动填充
FieldFill.INSERT_UPDATE 在inset和update时都可自动填充
在SoFast框架中,自动填充时由框架自动处理的,以下是实现类(内置在框架中),开发人员也可根据自己的需求进行定制实现。
@Component
@ConditionalOnClass(MetaObjectHandler.class)
public class SolMetaObjectHandler implements MetaObjectHandler {
private static final String CREAT_USER = "createUser";
private static final String CREAT_TIME = "createTime";
private static final String UPDATE_USER = "updateUser";
private static final String UPDATE_TIME = "updateTime";
private static final String DELETE_FLG = "deleteFlg";
@Autowired
private StrictFillProperties strictFillProperties;
/**
* 自动填充CREAT_USER、CREAT_TIME、删除FLG
*
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
// mybatis自动填充
Long userId = LoginUserContextHolder.getUserId();
this.strictInsertFill(metaObject, CREAT_USER, Long.class, userId);
this.strictInsertFill(metaObject, CREAT_TIME, Date.class, SolDateUtils.currentDate());
this.strictUpdateFill(metaObject, UPDATE_USER, Long.class, userId);
this.strictUpdateFill(metaObject, UPDATE_TIME, Date.class, SolDateUtils.currentDate());
this.strictInsertFill(metaObject, DELETE_FLG, Integer.class, Constants.DELETE_FLG_FALSE);
}
/**
* 自动填充UPDATE_USER和UPDATE_TIME
*
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, UPDATE_USER, Long.class, LoginUserContextHolder.getUserId());
this.strictUpdateFill(metaObject, UPDATE_TIME, Date.class, SolDateUtils.currentDate());
}
}