mybatis-plus 通用字段自动化(如逻辑删除和更新时间等)

一般来说某些项目比较规范的情况下,大多数表都会有逻辑删除字段和通用字段,例如更新时间,创建时间,更新人,创建人等等,但是在代码开发上会产生很多冗余的代码,逻辑删除的话,自己写比较繁琐,而且容易有遗漏逻辑。

本来打算自己写切面去实现,偶然发现mybatis-plus已经帮封装实现了,试了一下,很好用,所以分享一下。

逻辑删除

逻辑删除的意思就是某些业务表,在用户删除某条数据的时候,不真正删除,而是将此数据某字段改成类似“已删除”,而查询语句、更新语句等会忽略此条被逻辑删除的数据。
这里就不多介绍mybatis-plus的基础使用了,没接触过的小伙伴可以去官网研究一下,都是中文,很好看懂。
贴一下我们mybatis-plus的pom依赖:

 <!-- mybatis plus 核心依赖 -->
 <dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.4.0</version>
 </dependency>
 <!-- mybatis plus 代码生成器依赖 -->
 <dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-generator</artifactId>
  <version>3.4.0</version>
 </dependency>
 <!-- 代码生成器模板 -->
 <dependency>
  <groupId>org.apache.velocity</groupId>
  <artifactId>velocity-engine-core</artifactId>
  <version>2.1</version>
 </dependency>

逻辑删除比较简单,在3.3版本之后只要两步:

1.在配置文件中加入:

mybatis-plus:
 global-config:
  db-config:
   logic-delete-field: deleted # 全局逻辑删除的实体字段名
   logic-delete-value: 1 # 逻辑已删除值(默认为 1)
   logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

这里的deleted就是数据库表中表示逻辑删除与否的字段名,一般都是tinyint或者boolean,如果是boolean,logic-delete-value和logic-not-delete-value设置成true和false就行。

2.实体类字段上加上@TableLogic注解

  @TableLogic
  private Boolean deleted;

当然,一般自动生成的entity一般不建议做改动,因为entity和mapper经常会重新生成,这样加的代码就消失了,这里我们修改mybatis-plus代码生成器中的一个配置实现:

StrategyConfig strategy = new StrategyConfig();
// 省略命名规范、entity模式等其他配置
strategy.setLogicDeleteFieldName("deleted");

这里deleted同样是表字段名,而不是生成的类字段名。

加了这段配置后,自动生成的entity就会带有@TableLogic注解了。

在使用了封装化的逻辑删除后,mybatis-plus就能帮我们实现:

  • 调用mapper.delete类方法后,不删除对应的记录,而是将匹配到的记录的逻辑删除字段设置为我们设定的logic-delete-value值。
  • 调用查询语句包括selectList、selectById等语句或者更新语句时,会自动拼上逻辑删除字段的查询条件,达到不会查询出已逻辑删除的记录

通用字段自动化填充

如果说项目要求表设计上需要有一些通用字段,比如我现在做的项目每个主体表都需要有创建时间、更新时间、创建人、更新人这四个字段,mybatis-plus可以帮我们自动填充这四个字段,而不需要我们自己修改。
当然,这四个字段的获取逻辑必须是有通用方式的。

1.@TableField注解

@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;

@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;

这里只是一个例子,FieldFill.INSERT表示在执行insert类方法时会自动填充此字段,FieldFill.UPDATE是在执行update类方法时会自动填充此字段,除此之外还有FieldFill.INSERT_UPDATE表示插入和更新时都会填充。
当然,和逻辑删除一样,我们不会手动去加这个注解,还是依赖代码生成器的配置:

// 和逻辑删除一样的StrategyConfig,不要重复写
StrategyConfig strategy = new StrategyConfig();
// 省略命名规范、entity模式等其他配置
List<TableFill> tableFillList = new ArrayList<>();
tableFillList.add(new TableFill("create_time", FieldFill.INSERT));
tableFillList.add(new TableFill("create_user", FieldFill.INSERT));
tableFillList.add(new TableFill("update_time", FieldFill.UPDATE));
tableFillList.add(new TableFill("update_user", FieldFill.UPDATE));
strategy.setTableFillList(tableFillList);

这里的create_time、create_user等是表里的字段名,当mybatis-plus检测到表里有这些字段时,生成的entity会自动加上对应的@TableField注解。

2.自动填充处理类

@Component
public class MybatisPlusMetaFillHandler implements MetaObjectHandler {

  @Override
  public void insertFill(MetaObject metaObject) {
    this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
    this.strictInsertFill(metaObject,"createUser",
        ()-> {
          try{
           //这里是我自己项目获取当前session用户id的方法
            return Long.parseLong(UserContext.getUserInfo().get().getUserId());
          }catch(Exception ignored){
          }
          return null;
        }, Long.class);
  }

  @Override
  public void updateFill(MetaObject metaObject) {
    this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
    this.strictUpdateFill(metaObject,"updateUser",
        ()-> {
          try{
            //这里是我自己项目获取当前session用户id的方法
            return Long.parseLong(UserContext.getUserInfo().get().getUserId());
          }catch(Exception ignored){
          }
          return null;
        }, Long.class);
  }
}

自定义bean实现MetaObjectHandler接口,并实现insertFill方法和updateFill方法,this.strictUpdateFill方法中添加需要自动填充的entity字段名和填充Function,比如创建时间和更新时间,传入LocalDateTime::now方法,当然也可以用自定义的方法:

()->{
 //比方说我们更新时间不想太精确,只想设定为那一天的0点
 return LocalDateTime.now().toLocalDate().atStartOfDay();
}

这两个步骤完成后,mybatis-plus就可以自动填充此字段了,比如在新增一条记录时,只需要set此记录的业务值,不设置create_time和create_user,直接调用entity.insert()方法,可以在数据库新增的记录中看到create_time自动填充了当前时间,create_user自动填充了session中的当前用户id。

这是字段自动填充一个应用,可拓展方向有很多,大家可以多多思考,自行发挥。

到此这篇关于mybatis-plus 通用字段自动化(如逻辑删除和更新时间等)的文章就介绍到这了,更多相关mybatis-plus 字段自动化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 关于Mybatis-Plus字段策略与数据库自动更新时间的一些问题

    字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" 问题描述: 当字段策略为 0 "忽略判断" 的时候,如果实体和数据库有字段是需要自动更新的,例如update_time,更新某条记录的时候自动刷新update_time,理论上我们在业务控制的时候是不需要设置update_time的,利用数据库特性就好,但是在该字段策略下,业务逻辑要更新字段(没有主动设置 update_time),这时候因为忽略判断,

  • Mybatis-Plus自动填充更新操作相关字段的实现

    在阿里开发手册的建表规约中有说明,数据库表中应该都要有create_time.update_time字段:那么在开发中,对于这些共有字段的处理应该要进行统一,这样就可以简化我们的开发过程.那么本文就对Mybatis-Plus中的字段自动填充进行记录. 场景介绍 在项目的数据表设计中,每张表都有create_id.create_time.update_id.update_time这四个字段,那么在Java应用中,针对新增和修改操作要对这四个字段进行相应的更改: create_id.update_i

  • mybatis-plus主键id生成、字段自动填充的实现代码

    一.主键id的生成 数据库表里通常都会有一个主键id,来作为这条数据的唯一标识. 常见的方式 1.数据库自动增长 这种很常见了,可以做到全库唯一.因为id是天然排序的,对于涉及到排序的操作会很方便. 2.UUID 上面的自动增长,虽然简单,但是对于分表这样的操作来说就比较麻烦.因为你在第二张插入数据的时候,需要拿到上一张表最后一个数据的id. UUID则不同,每次都一个随机唯一的值,不过因为是随机,所以也就没有排序了. 3.redis redis也可以用来生成id,利用redis的原子操作.好处

  • SpringBoot Mybatis Plus公共字段自动填充功能

    一.应用场景 平时在建对象表的时候都会有最后修改时间,最后修改人这两个字段,对于这些大部分表都有的字段,每次在新增和修改的时候都要考虑到这几个字段有没有传进去,很麻烦.mybatisPlus有一个很好的解决方案.也就是公共字段自动填充的功能.一般满足下面条件的字段就可以使用此功能: 这个字段是大部分表都会有的. 这个字段的值是固定的,或则字段值是可以在后台动态获取的. 常用的就是last_update_time,last_update_name这两个字段. 二.配置MybatisPlus 导包:

  • mybatis-plus 通用字段自动化(如逻辑删除和更新时间等)

    一般来说某些项目比较规范的情况下,大多数表都会有逻辑删除字段和通用字段,例如更新时间,创建时间,更新人,创建人等等,但是在代码开发上会产生很多冗余的代码,逻辑删除的话,自己写比较繁琐,而且容易有遗漏逻辑. 本来打算自己写切面去实现,偶然发现mybatis-plus已经帮封装实现了,试了一下,很好用,所以分享一下. 逻辑删除 逻辑删除的意思就是某些业务表,在用户删除某条数据的时候,不真正删除,而是将此数据某字段改成类似"已删除",而查询语句.更新语句等会忽略此条被逻辑删除的数据. 这里就

  • Mybatis plus通用字段自动填充的示例

    在进行持久层数据维护(新增或修改)的时候,我们通常需要记录一些非业务字段,比如:create_time.update_time.update_by.create_by等用来维护数据记录的创建时间.修改时间.修改人.创建人等信息.通常情况下我们需要对这些字段进行手动赋值.赋值的过程也比较冗余,都是重复操作. 通常是为create_time赋值为系统的当前时间.update_time赋值为系统修改操作执行时的当前时间. create_by(创建人).update_by(修改人)赋值为当前的登录用户的

  • MyBatis-Plus解决逻辑删除与唯一索引的问题

    目录 简介 问题复现 建库建表 代码 测试 解决方案 方案1:将字段设置为id(推荐) 方案2:将字段设置为当前时间(不推荐) 简介 说明 本文用示例介绍MyBatis-Plus如何解决逻辑删除与唯一索引的问题. 物理删除与逻辑删除 数据是很重要的,数据库里的数据在删除时一般不会用DELETE语句直接物理删除. 通常的做法是使用逻辑删除,也就是:新加一个标记是否删除的字段,在删除时不是真的删除,而是使用UPDATE语句将某个字段设置为删除状态.例如:"deleted_flag",0表示

  • 详解MyBatisPlus逻辑删除与唯一索引冲突问题

    1.问题背景: 在开发中,我们经常会有逻辑删除和唯一索引同时使用的情况.但当使用mybatis plus时,如果同时使用逻辑删除和唯一索引,会报数据重复Duplicate entry的问题. 举个例子: 原来数据库结构: 这里location_id是唯一索引 CREATE TABLE `eam_location` ( `id` int(11) NOT NULL AUTO_INCREMENT, `location_id` varchar(50) UNIQUE NOT NULL COMMENT '位

  • Mybatis plus逻辑删除失败的BUG操作

    开发调试的时候发现Mybatis Plus的逻辑删除失效了,看了下配置文件发现没有问题,通过查看以下源码发现 逻辑删除需要注入的bean,查看这个bean的源码如下 查看其中一个实例的类的源码,如通过ID逻辑删除LogicDeleteById的源码,如下 mp在项目启动时预加载SQL是通过TableInfo中logicDelete字段判断是否开启逻辑删除的.然后让我们来看看mp内部是如何判断是否开启逻辑删除的. 先看如下源码 大概就是讲实体类中的字段进行循环映射数据库字段并封装到TableFie

  • Mybatis plus逻辑删除注解@TableLogic的使用

    目录 物理删除和逻辑删除 @TableLogic注解 @TableLogic注解默认值: @TableLogic注解用法 首先这个注解是苞米豆出品,也就是我们常说的mybatis升级版的东西. 简单讲一下这个注解的用法:我们在做数据库设计的时候有时候哪怕是删除也不会真的走物理删除,毕竟这样很多数据就不可恢复了,大多数时候很多删除都是用逻辑删除. 物理删除和逻辑删除 简单来说物理删除就是真的把这条数据从数据库删除了.而逻辑删除主要是把表中的某一个字段作为标识符,一般我们常用的会默认初始为0,当我们

  • mybatis plus实现分页逻辑删除

    一.分页 通过mybatis-plus实现分页,也是很简单,插件大法. 1.配置分页插件 把分页的插件也配置到统一的配置类里: @Configuration // 配置扫描mapper的路径 @MapperScan("com.pingguo.mpdemo.mapper") public class MpConfig { // 乐观锁插件 @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { re

  • MyBatis Plus逻辑删除和分页插件使用详解

    概要:Mybatis plus 官网链接 :https://mp.baomidou.com/guide/ 一.依赖配置: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" x

  • MyBatis-Plus逻辑删除和字段自动填充的实现

    目录 一.ID生成策略 1.使用@TableId注解 2.全局ID生成策略 二.逻辑删除 1.全局配置 2.使用@TableLogic注解 三.字段自动填充 1.指定字段自动填充 2.自定义MetaObjectHandler 3.测试 四.执行SQL分析打印 1.添加 spy.properties配置文件 2.修改数据源配置 3.测试查询 一.ID生成策略 1.使用@TableId注解 @TableId注解:主键注解 使用位置:实体类主键字段. @Data @ToString @TableNam

  • tk.mybatis扩展通用接口使用详解

    一.tk.mybatis已经为我们封装好了许多拆箱即用的通用mapper,但在实际的项目开发中想必不少小伙伴在数据库设计中都会采用逻辑删除这种方案,再去使用通用的mapper接口就不行了. 这时候就需要我们封装一些扩展的通用Mapper接口. 二.项目中提供了大量现成的方法,这些方法可以作为扩展时的参考. 例如 selectAll 方法. 首先定义接口: @RegisterMapper public interface SelectAllMapper<T> { /** * 查询全部结果 * *

随机推荐