👨?🎓作者:bug菌
??博客:CSDN、掘金等
💌公众号:猿圈奇妙屋?
🚫特别声明:原创不易,转载请附上原文出处链接和本文声明,谢谢配合。
🙏版权声明:文章里可能部分文字或者图片来源于互联网或者百度百科,如有侵权请联系bug菌处理。
?一、前言🔥
? ? ? ? 在日常开发中,特别是一些业务系统项目,共同发现一个规律,那就是对于诸多业务表中都包含有相同的字段,比如id主键、uuid、create_time、create_by、update_by、update_time等。而这些字段也是对于有些表而言是必要存在的。
? ? ? ? 既然字段可以说是一模一样,那作为有代码洁癖的我,怎么可以忍受,每个实体都需要重复创建这些字段。我数了一下,业务规模最庞大最复杂的人员申报系统,拥有64张业务表,其中有32张表是含有以上全部字段属性的,为什么不封装??我不理解。
- 第一每个实体中都有这些字段的身影,为何不封装?
- 第二这些字段在常规的增删改中都是需要进行手动赋值,为何不抽离公共方法实现?
? ? ? ? 而今天我想做的事,就是把它们都剥离出来,改造!优雅永不过时。
- 第一抽一个公共Entity出来。
- 第二不需要人为手动为这些字段赋值。
二、实现思路🔥
思路1:
? ? ? ? 采用aop进行自定义注解法。实现很简单,为添加了自定义注解切面赋值。我就不过多介绍,重点是看思路2,方便快捷。
思路2:
? ? ? ? 采用mybatis-plus提供的@TableField 注解实现字段内容自动填充。
? ? ? ? ?卑微小弟插播一条广告。若小伙伴们在批阅文章的过程中如果觉得文章对您有一丝丝帮助,还请别吝啬您手里的赞呀,大胆的把文章点亮👍吧,您的点赞三连(收藏??+关注👨?🎓+留言📃)就是对bug菌我创作道路上最好的鼓励与支持😘。时光不弃🏃🏻?♀?,创作不停💕,加油?
三、实现方案🔥
? ? ? ? 想必大家对mybatis-plus都不陌生吧,这里我就不过多介绍它了,我们直接步入正题。
第一步:引入pom依赖
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
第二步:实体类添加注解属性
????????在你需要自动填充的字段加上注解。我这里是已经将众多表中共同字段抽离到了一个公共实体类中,而这也是解决我上方提出的第一步。而你也可以只加到你需要自动填充的字段上,加上该注解即可。后续也可以单独在某个字段上添加,因为一定要数据库自带这些字段才行,否则直接配置肯定是会映射不上而报错的。
@TableField(fill = FieldFill.INSERT) //执行插入时自动填充
拓展:
? ? ? ? 如下是四中填充策略,你们具体根据业务进行选取。
public enum FieldFill {
/**
* 默认不处理
*/
DEFAULT,
/**
* 插入填充字段
*/
INSERT,
/**
* 更新填充字段
*/
UPDATE,
/**
* 插入和更新填充字段
*/
INSERT_UPDATE
}
????????如下是完整添加。供大家参考:
package com.example.review.vo;
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 lombok.Data;
import java.util.Date;
/**
* 公共属性实体类
*
* @author luoYong
* @create 2022年3月29日00:00:49
*/
@Data
public class BaseEntity {
/**
* id 生成策略为UUID
*/
@TableId(type = IdType.UUID)
private String id;
/**
* 创建者 填充策略为插入自动填充
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间 填充策略为插入自动填充
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新者 填充策略为插入和更新填充字段
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/**
* 更新时间 填充策略为插入和更新填充字段
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
? ? ? ? 你以为添加了就能用了吗?不不不,还差最后一步,那就是实现mp提供的填充器。而填充原理是直接给entity 的属性设置值!!!注解则是指定该属性在对应情况下必有值,如果无值则入库会是null。
第三步:实现填充器
? ? ? ? 没有这一步,自动填充肯定是不行的,如下我就给大家讲解一下,如何实现填充器?
你只需要按如下代码,具体实现insertFill()跟 updateFile() 接口即可。?
如下是完整实现。供大家参考:
package com.example.review.handlers;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.example.review.util.UserUtil;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 自动补充插入或更新时的值
* @author luoYong
* @date 2022年3月28日12:35:45
*/
@Component
public class MpMetaObjectHandler implements MetaObjectHandler {
/**
* 插入时的填充策略
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createBy", UserUtil.getUsername(),metaObject);
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateBy", UserUtil.getUsername(),metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
/**
* 更新时的填充策略
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateBy", UserUtil.getUsername(),metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
????????如上我是又封装了一个获取当前登录用户信息的静态类,UserUtil.getUserName(),可直接获取登陆系统的用户信息,然后设置当前时间,切记一点,数据库字段和填充器字段必须对应上,否则无效啊。比如' createBy ' 对应数据库字段为 ' create_by ';命名规律是根据驼峰命名。这样讲大家可曾明白?
第四步:接口测试
? ? ? ? 这里咱们就写两个接口,一个新增接口,一个修改接口,分别测试insert() 与update()。
具体接口如下:
/**
* 插入用户
*/
@GetMapping("/insert")
@ApiOperation(value = "插入用户",notes = "插入用户")
public String insert(){
UserEntity userEntity = new UserEntity();
userEntity.setName("我是bug菌");
userMapper.insert(userEntity);
//返回插入的id
return userEntity.getId();
}
?????????然后将上方插入接口返回的uuid手动给到下边,我图省事,直接就在代码中给大家演示啦,讲道理实现逻辑不会写到控制层的。
/**
* 修改用户
*/
@GetMapping("/update")
@ApiOperation(value = "修改用户",notes = "修改用户")
public void update(){
UserEntity userEntity = new UserEntity();
userEntity.setName("我是bug菌No.1");
userEntity.setId("b6ef69a870966502dcaa595deea00435");
userMapper.updateById(userEntity);
}
? ? ? ? 然后重启项目,我们 swagger 调用一下:我们查看一下控制台输出打印:
==> Preparing: INSERT INTO user ( id, create_by, create_time, update_by, name, update_time ) VALUES ( ?, ?, ?, ?, ?, ? )
==> Parameters: ad7a97a8ca1533423d5d06f653c43e79(String), xxx(String), 2022-03-29 00:23:09.355(Timestamp), xxx(String), 我是bug菌(String), 2022-03-29 00:23:09.355(Timestamp)
? ? ? ? ?ok,眼瞅这执行sql,证明这条数据新增成功了,而且,我们想看到的自动填充的字段内容也设置上了,这证明新增时手动实现的填充器方法insertFill()中为这create_time、create_by、update_by、update_time这4个字段赋值是准确有效的。
? ? ? ? 接下来我们将返回的uuid进行查验修改接口,看是否update()方法设置update_by、update_time这两个字段是否也能自动填充对应数据?
? ? ? ? ?项目再接着重启一波,然后swagger调用修改接口试试,看看控制台打印内容吧。
Preparing: UPDATE user SET update_by=?, name=?, update_time=? WHERE id=?
Parameters: xxx(String), 我是bug菌No.1(String), 2022-03-29 00:29:59.889(Timestamp), ad7a97a8ca1533423d5d06f653c43e79(String)
? ? ? ? 很明显控制台打印的执行sql,这两个字段具体数据也被设置上了。很完美,直接证实了我给出的解决方案是完美的。看这种实现方式是不是优雅、简洁多了,相比不封装而言?
????????最后检查一下数据库数据。再核实一遍;肉眼可见,也是没任何问题的。
? ? ? ? 好啦,以上就是这期的全部内容啦,如果对你有所帮助,还请不要忘记给bug菌[三连支持]哟。如果想获得更多的学习资源或者想和更多的技术爱好者一起交流,可以关注我的公众号『猿圈奇妙屋』,后台回复关键词领取学习资料、大厂面经、面试模板等海量资源,就等你来拿。
四、文末🔥
????????如果你还想要学习更多,小伙伴们大可关注bug菌专门为你们创建的专栏《mybatis-plus实战》,都是我一手打下的江山,持续更新中,希望能帮助到更多小伙伴们。
? ? ? ?我是bug菌,一名想走👣出大山改变命运的程序猿。接下来的路还很长,都等待着我们去突破、去挑战。来吧,小伙伴们,我们一起加油!未来皆可期,fighting!
最后送大家两句话,与诸君共勉!
??做你想做的人,没有时间限制,只要愿意,什么时候都可以start,
🍀你能从现在开始改变,也可以一成不变,这件事,没有规矩可言,你可以活出最精彩的自己。
????
💌如果文章对您有所帮助,就请留下您的赞吧!(#^.^#);
💝如果喜欢bug菌分享的文章,就请给bug菌点个关注吧!(?′?‵?)づ╭?~;
💗如果对文章有任何疑问,还请文末留言或者加群吧【QQ交流群:708072830】;
💞鉴于个人经验有限,所有观点及技术研点,如有异议,请直接回复参与讨论(请勿发表攻击言论,谢谢);
💕版权声明:原创不易,转载请附上原文出处链接和本文声明,版权所有,盗版必究!!!谢谢。
|