mybatisplus自动填充时间_mybatis plus 自动更新数据库时间的小坑

在处理测试提出的bug时,发现MyBatisPlus更新数据时未自动更新modifiedTime字段。问题在于更新前先查询导致modifiedTime已有值。解决方案包括:1) 直接更新,避免查询;2) 使用@TableField结合@update注解;3) 利用@TableField的fill注解进行填充。
摘要由CSDN通过智能技术生成

描述问题

        昨天测试又给我提了一个bug(我怎么觉得自己是个被bug驱动的渣渣程序员),说他更新了某条数据, 但是这条数据的修改时间没有变化. 我的第一反应是怎么可能,我在创建数据库表的时候明明设置了修改时间会自动更新呀? 但是人家就是测试这么个bug呀, 我也只能认怂, 修吧. 经过一番查找, 最后确定, 是我的代码写的有问题, 这里我重现一下犯罪现场, 对自己以兹鼓励哈.

犯罪数据准备

假设我们的数据库表如下所示, 注意这里的create_time和modified_time的设置, 二者都会在插入数据时自动填充, 并且modified_time会在更新数据时自动更新. 不行你可以在数据库中执行插入和更新试试就一目了然了.

CREATE TABLE `user_info`  (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID自增',
`username` varchar(64) NOT NULL COMMENT '用户名',
`mobile` varchar(128) NOT NULL COMMENT '手机号',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '0:未删除 1:已删除',
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '用户信息表' ROW_FORMAT = Dynamic;
犯罪代码准备
// doamin
@Data
public class UserInfo {

@TableId(type = IdType.AUTO)
private Long id;

private String username;

private String mobile;

private Integer deleted;

private LocalDateTime createdTime;

private LocalDateTime modifiedTime;
}

// controller
@RestController
@RequestMapping("/date/user")
public class UserInfoController {


@Resource
private UserInfoService userInfoService;

// 保存一条数据
@RequestMapping("/save")
public boolean createUserInfo(@RequestBody @Validated CreatUserInfoRequest request) {

UserInfo userInfo = new UserInfo();
BeanUtils.copyProperties(request, userInfo);

boolean sucess = userInfoService.save(userInfo);
return sucess;
}

// 更新一条数据
@RequestMapping("/update")
public boolean updateUserInfo(@RequestBody @Validated UpdateUserInfoRequest request) {

UserInfo userInfo = userInfoService.getById(request.getId());
Assert.notNull(userInfo, "编辑的信息不存在");

BeanUtils.copyProperties(request, userInfo);
boolean success = userInfoService.updateById(userInfo);

return success;
}
}
犯罪过程重现

执行插入操作: de0b57059c0f8a3a466187f852ba5d4d.png 

数据库结果: 740b300d2166729a1c4b1009461ebb74.png

插入时执行的sql: 31804cce3c472713b1c9176b23174d45.png

执行更新操作: b880df5e4a489dc48b3455942ee734db.png

数据库结果: 90a064e0d97c782397f1022ef93e9392.png

更新时执行的sql: 82b5e8c7f2bd07c81f1a524c7ef75ea8.png

看到这里, 我相信眼睛犀利的你应该已经发现我哪里错了, 是的, 就是你想的那样, 我在执行更新操作之前, 首先把这个对象查询出来了, 然后把属性值赋予他之后,我才去执行了更新, 此时我使用的对象正是我查询出来的, 而它的modifiedTime是有值的, 我每次给人家更新成最开始的时间,还埋怨人家咋不给我自动更新, 做人难, 做代码也挺难. 既然知道了原因, 那就改吧.

毁尸灭迹啦
方法1---直接更新, 不要先查询----核心是保证modifiedTime 没有值
    @RequestMapping("/update")
public boolean updateUserInfo(@RequestBody @Validated UpdateUserInfoRequest request) {

UserInfo userInfo = new UserInfo();

BeanUtils.copyProperties(request, userInfo);
boolean success = userInfoService.updateById(userInfo);

return success;
}

162056a99b993904e6aafa9d5c0c2225.png a829dde9b564657d96e72953e553f48d.png

    @RequestMapping("/update")
public boolean updateUserInfo(@RequestBody @Validated UpdateUserInfoRequest request) {

UserInfo userInfo = userInfoService.getById(request.getId());
Assert.notNull(userInfo, "编辑的信息不存在");

BeanUtils.copyProperties(request, userInfo);
userInfo.setModifiedTime(null);

boolean success = userInfoService.updateById(userInfo);

return success;
}

fa8df3feabb553019dcbb4acbac20309.png dc2e371b39f71ee00c57308e4b203374.png

方法2----使用@TableField + update注解

@TableField(update = "now()")
private LocalDateTime modifiedTime;

18c74e18501508c9c0c35d864a5d861e.png e3a3fb664016143ed0e73c6b8e4d376e.png fb382cf52199990ca0e9c2bb0a22cd5d.png

方法三-----使用@TableFiled + fill 注解


@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime modifiedTime;

@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert field....");
this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);
this.setFieldValByName("modifiedTime", LocalDateTime.now(),metaObject);
}

@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("modifiedTime", LocalDateTime.now(),metaObject);
}
}

ab3d7d21074efce0715ae7cf5bb937c2.png 5253a3a50d6cfe488184e10fa09415ba.png c5cadd3e0b250357c6f81a38e8981694.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值