配置公共字段全局填充createTime和updateTime

我们的数据库表中一般都会有几个公共字段,这些字段的值不需要手动设置,全局配置后,就会自动填充公共字段值。

一、创建公共表字段

  • 每个数据库表中公共字段一般包括主键id、创建时间createTime、更新时间updateTime、逻辑删除字段isDelete等。
  • 创建mysql数据库中的用户表字段如下
    在这里插入图片描述

1、 公共字段实体类

/**
 * 实体父类
 *
 * @author wangjiao
 * @since 2020/11/13
 */
@Data
@SuperBuilder
@ApiModel("BaseEntity")
@AllArgsConstructor
@NoArgsConstructor
public abstract class BaseEntity implements Serializable {

  @ApiModelProperty(value = "主键ID,这里使用自增ID")
  @TableId(value = "id", type = IdType.AUTO)
  private Long id;

  @ApiModelProperty(value = "创建时间")
  @TableField(value = "create_time", fill = FieldFill.INSERT)
  private Date createTime;

  @ApiModelProperty(value = "更新时间")
  @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
  private Date updateTime;

  @ApiModelProperty(value = "逻辑未删除:0,逻辑已删除:1")
  private Boolean isDelete;
}
  • 注解@TableId(value = “id”, type = IdType.AUTO) 的type = IdType.AUTO,表示主键id字段自增;
  • @TableField(value = “create_time”, fill = FieldFill.INSERT)的fill = FieldFill.INSERT,表示在新增数据时自动填充日期,需要去全局配置后该注解才生效;
  • @TableField(value = “update_time”, fill = FieldFill.INSERT_UPDATE)的 fill = FieldFill.INSERT_UPDATE,表示在新增或修改数据时自动填充日期,需要去全局配置后该注解才生效。
  • isDelete:逻辑删除字段数据库默认false,需要在yml文件中配置才生效,逻辑删除配置如下
    在这里插入图片描述

2、User实体类,继承公共实体类

  • UserPoJo是与service层相互关联的,数据库字段以下划线分隔,实体字段以小驼峰形式命名,如:create_time对应实体createTime;
  • service接口:public interface UserService extends BaseService {},进行数据操作时,sql字段与实体会自动进行转换。
  • 当数据库表名称与实体名称不一致时,需要在实体类上注明表名称:@TableName(value = “tb_user”),这样数据库表字段才能正确映射到对应的实体字段。
  • 为了使我们的程序更具高内聚低耦合,各个模块做好各自的事情,我们将实体分为pojo(与数据库进行交互service层),request(客户端请求入参交互controller层),response(服务端对数据进行处理后返回给客户端的数据信息)
    在这里插入图片描述
  • UserPoJo实体代码清单
/**
 * 用户信息
 *
 * @author WangJiao
 * @since 2019-12-19
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("用户表")
@TableName(value = "tb_user")
public class UserPoJo extends BaseEntity {

  @ApiModelProperty(value = "电话", example = "156****12")
  private String tel;

  @ApiModelProperty(value = "密码", example = "******")
  private String password;

  @ApiModelProperty(value = "用户头像", example = "http://test.jpg")
  private String avatar;

  @ApiModelProperty(value = "姓名", example = "周深")
  private String name;

  @ApiModelProperty(value = "账号状态1:正常,2:停用", example = "1")
  private Integer status;

  @ApiModelProperty(value = "openId", example = "34655*********6774df")
  private String openId;

  public static UserPoJo of() {
    return new UserPoJo();
  }

  public static UserPoJo of(UserReq req) {
    UserPoJo poJo = UserPoJo.of();
// bean工具类,将一个实体对象属性赋值给另一个实体对象,这两个实体中的属性字段名称和字段类型必须保持一致,否则将拷贝不成功
    BeanUtils.copyProperties(req, poJo);
    return poJo;
  }
}
  • UserReq实体,一般会对入参进行简单的校验;
/**
 * 用户信息请求
 *
 * @author WangJiao
 * @since 2019-12-19
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("用户信息请求")
public class UserReq implements Serializable {
  private static final long serialVersionUID = 1L;

  @NotBlank(message = "电话不能为空")
  @ApiModelProperty(value = "电话", example = "156****12")
  private String tel;

  @NotBlank(message = "密码不能为空")
  @ApiModelProperty(value = "密码", example = "*****")
  private String password;

  @NotBlank(message = "确认密码不能为空")
  @ApiModelProperty(value = "确认密码", example = "*****")
  private String rePassword;

  @ApiModelProperty(value = "用户头像", example = "http://test.jpg")
  private String avatar;

  @NotBlank(message = "用户名不能为空")
  @ApiModelProperty(value = "姓名", example = "周深")
  private String name;

  public static UserReq of() {
    return new UserReq();
  }
}
  • UserResponse 返回给客户端需要的信息,一般不包含敏感信息
/**
 * 用户信息Response
 *
 * @author WangJiao
 * @since 2019-12-19
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("用户信息Response")
public class UserResponse extends BaseEntityResponse {

  @ApiModelProperty(value = "电话", example = "156****12")
  private String tel;

  @ApiModelProperty(value = "用户头像", example = "http://test.jpg")
  private String avatar;

  @ApiModelProperty(value = "姓名", example = "周深")
  private String name;

  @ApiModelProperty(value = "账号状态1:正常,2:停用", example = "1")
  private Integer status;

  public static UserResponse of() {
    return new UserResponse();
  }

  public static UserResponse of(UserPoJo poJo) {
    UserResponse response = UserResponse.of();
// bean工具类,将一个实体对象属性赋值给另一个实体对象,这两个实体中的属性字段名称和字段类型必须保持一致,否则将拷贝不成功
    BeanUtils.copyProperties(poJo, response);
    return response;
  }
}

二、未全局配置时操作接口测试

  • 编写一个新增用户数据接口

1、新增用户信息接口

  • 新增用户信息接口代码清单如下
  • 此时在写入或更新数据时未全局配置创建时间和更新时间,也没有手动设置者两个字段的值,所以数据库表中的create_time和update_time字段的值是空值。
  • UserController代码清单
/**
 * 用户注册
 *
 * @param req 注册信息
 * @return obj
 */
@PostMapping("/register")
@ApiOperation("注册")
public ApiResult register(@Valid @RequestBody UserReq req) {
  log.info("register:user register info[req:{}]", JSON.toJSONString(req));
  // 新增用户条件密码校验判断
  if (!Objects.equals(req.getPassword(), req.getRePassword())) {
    return ApiResult.fail(ApiCode.USER_TWO_PASSWORDS_INCONSISTENT);
  }
  // 手机号作为账号唯一性校验
  UserPoJo findUser = service.getByTel(req.getTel());
  if (Objects.nonNull(findUser)) {
    return ApiResult.fail(ApiCode.USER_ACCOUNT_REGISTERED);
  }

  // 密码进行md5加密
  req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
  boolean res = service.saveUser(UserPoJo.of(req));
  log.info("register:[res:{}]", res);
  return ApiResult.ok(res);
}
  • UserService 保存用户信息接口
/**
 * save userInfo
 *
 * @param of user
 * @return true
 */
boolean saveUser(UserPoJo of);
  • UserServiceImpl 保存用户信息接口实现
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveUser(UserPoJo of) {
  boolean save = this.save(of);
  log.info("saveUser:[save:{}]", save);
  return save;
}

2、启动项目新增一条用户数据

  • 向数据库用户表中插入一条数据
    在这里插入图片描述
  • 数据库中create_time和update_time字段是的值没有自动填充
    在这里插入图片描述

三、全局配置公共字段填充

1、在common模块创建config和handler

在这里插入图片描述

2、handler中创建MetaHandler类实现MetaObjectHandler

  • 用于处理全局填充公共字段,代码清单如下。
package yooo.yun.com.common.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 处理新增和更新的基础数据填充,配合BaseEntity和MyBatisPlusConfig使用
 *
 * @author wangjiao
 * @since 2020/1217
 */
@Component
public class MetaHandler implements MetaObjectHandler {

  /**
   * 新增数据执行
   *
   * @param metaObject metaObject
   */
  @Override
  public void insertFill(MetaObject metaObject) {
    this.setFieldValByName("createTime", new Date(), metaObject);
    this.setFieldValByName("updateTime", new Date(), metaObject);
  }

  /**
   * 更新数据执行
   *
   * @param metaObject metaObject
   */
  @Override
  public void updateFill(MetaObject metaObject) {
    this.setFieldValByName("updateTime", new Date(), metaObject);
  }

  public static MetaHandler of() {
    return new MetaHandler();
  }
}

3、config中创建MybatisPlusConfig类

package yooo.yun.com.common.config;

import com.baomidou.mybatisplus.core.config.GlobalConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import yooo.yun.com.common.handler.MetaHandler;

/**
 * MybatisPlus配置
 *
 * @author wangjiao
 * @since 2020/12/17
 */
@Configuration
public class MybatisPlusConfig {

  /**
   * 自动填充功能
   *
   * @return GlobalConfig
   */
  @Bean
  public GlobalConfig globalConfig() {
    GlobalConfig globalConfig = new GlobalConfig();
    globalConfig.setMetaObjectHandler(MetaHandler.of());
    return globalConfig;
  }
}

四、全局配置后操作接口测试

1、重启项目进行新增数据测试

在这里插入图片描述

  • 数据库新增的数据创建时间和更新时间字段的值已经自动填充上了
    在这里插入图片描述
    -:来到这里,相信你已经get到了喔!!!
    在这里插入图片描述
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值