当前位置: 首页 > article >正文

Java开发 - 公共字段的自动填充

前言

如果说Java开发中有什么是让人很烦的一件事,那一定是无尽的填充字段,本篇作为观众瑰宝系列第二篇,将带来公共字段填充相关的知识点,学完此篇,让你摆脱公共字段填充带来的麻烦,节省代码,降低冗余,妥妥的给项目瘦身,还能一定程度上提高程序的运行效率,所以,你心动吗?

问题描述

可以说,几乎每张表,我们都会有create_time,update_time这样的公共字段,所以几乎每次请求时我们都要去操作这样的字段并重新赋值,这就降低了我们的开发效率,且重复的代码让人不胜其烦,所以我们想要写一个公共的方法可以统一添加这些字段,而不用处处都写相同的代码!

问题分析

我们以上一篇SpringCache的项目为基础,也可自行创建一个项目,在上一个项目中,我们在原来的数据库中添加create_time,update_time字段:

alter table user add create_time DATETIME;
alter table user add update_time DATETIME;

新表字段如下: 

我们清空了表中的数据, 记者修改模型数据,添加这两个新字段;

package com.codingfire.cache.entity;

import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

@Data
public class User implements Serializable {
    private Long id;
    private String username;
    private String password;
    private Integer age;
    private String phone;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

接着去重新修改增删改查的代码,我们简单修改如下:

    @PostMapping
    @CachePut(value = "user", key = "#user.id")
//    @CachePut(value = "userCache", key = "#backUser.id")
    public User add(User user) {
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userService.save(user);
        User backUser = user;
        return backUser;
    }

    @PutMapping
    @CachePut(value = "user", key = "#user.id")
//    @CachePut(value = "userCache", key = "#backUser.id")
    public User update(User user) {
        user.setUpdateTime(LocalDateTime.now());
        userService.updateById(user);
        User backUser = user;
        return backUser;
    }

下面运行MySQL和Redis服务,用postman调用添加用户接口:

结果意外遇到了新问题, Redis的jackson不支持LocalDateTime时间类,这就尴尬了,但并不是无解,报错中给出了解决办法,我们按照提示做出一些调整。

添加新依赖:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.13.0</version>
</dependency>

这时如果你直接运行项目,还是不行,还需要在实践属性上添加两个注解:

    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)

做完这些,重新启动项目,运行添加用户的API,果然运行成功,我们查看数据库:

 新的数据已经添加上去了,但又没有办法隐式的添加这两个时间,而不是直接通过代码呢?我想,应该是有的,我们之前学过过滤器和拦截器,他俩的差别我就不再介绍了,感兴趣的自行查看: 

Java开发 - 拦截器初体验_CodingFire的博客-CSDN博客

由此来看,这里面必定少不了他们的角色,这里我们就用过滤器吧,过滤器的拦截范围更大,一般项目都会使用,我们不妨也用一下,基调定好了,下一步我们就来看看怎么实现这个过滤器,让字段可以自动填充。 

然而我们发现,写在过滤器里也不是很合适,它只能在post时通过request.getParam(key)获取数据,不能进行写操作,这就麻烦了,看来过滤器也不是很好的选择啊。

好在,天无绝人之路,我们还可以通过自定义元数据对象处理器的方式来统一添加参数,而且,可行度非常高。

解决方案

创建元数据对象处理器

package com.codingfire.cache.common;

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

import java.time.LocalDateTime;

/**
 * 自定义元数据对象处理器
 */
@Component
@Slf4j
public class MyMetaObjectHandle implements MetaObjectHandler {
    /**
     * 插入操作,自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自动填充[insert]...");
        log.info(metaObject.toString());

        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime",LocalDateTime.now());
    }

    /**
     * 更新操作,自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自动填充[update]...");
        log.info(metaObject.toString());

        metaObject.setValue("updateTime",LocalDateTime.now());
    }
}

删除接口内自定义添加字段

将接口中,我们手动添加的字段删掉:

    @PostMapping
    @CachePut(value = "user", key = "#user.id")
//    @CachePut(value = "userCache", key = "#backUser.id")
    public User add(User user) {
        userService.save(user);
        User backUser = user;
        return backUser;
    }

给时间字段添加注解

做完这些,还需要给自动填充的字段增加一个注解。

如果是插入填充:

    @TableField(fill = FieldFill.INSERT)

如果是插入和更新时都填充:

    @TableField(fill = FieldFill.INSERT_UPDATE)

测试

我们重新启动项目,用postman调用此接口,新增加一个用户:

查看数据库中新增加的用户信息是否包含了时间:

 

测试成功,公共字段的填充搞定。 

结语

看来,解决问题时,方向一定要找对,斗则方向错了,怎么也不可能完成目标的。一开始博主想要用过滤器来完成,但是发现过滤器无法进行写操作,转而更换了方向,从元数据处理器下手,最后终于实现了公共字段填充。觉得不错,就给个赞吧。


http://www.kler.cn/a/11681.html

相关文章:

  • 准确--FastDFS快速单节点部署
  • 【论文阅读】利用SEM二维图像表征黏土矿物三维结构
  • 将 Docker 镜像保存到本地文件系统中
  • gitlab角色、权限
  • java并发编程JUC:四、volatile(保证可见性、防止指令重排、双重校验锁实现对象单例)
  • 安卓智能对讲终端|北斗有源终端|三防对讲机|单兵终端|单北斗
  • 第十四天本地锁、Redis分布锁、Redisson锁三者的区别
  • 什么是MVVM?
  • Kafka是如何支持百万级TPS的?
  • Pandas2.0它来了,这些新功能你知道多少?
  • 冥想第七十六十三天
  • 使用Go语言打造轻量级Web框架
  • 【学习笔记】Linux基础
  • 【排序】【二分】【角度制】个人练习-Leetcode-1610. Maximum Number of Visible Points
  • 【高危】Apache Linkis <1.3.2 存在反序列化漏洞(CVE-2023-29216)
  • 初识C语言————3
  • Vue3——一文入门Vue3
  • Python圈的普罗米修斯——一套近乎完善的监控系统
  • 「SQL面试题库」 No_34 连续空余座位
  • Python的并发编程-3
  • nginx
  • js 身份证最后一位计算
  • SQL——多表连接查询
  • 一种供水系统物联网监测系统
  • ROS1学习笔记:常用可视化工具的使用(ubuntu20.04)
  • 【LeetCode: 剑指 Offer II 112. 最长递增路径 | 递归 | DFS | 深度优先遍历 | 记忆化缓存表】