一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - mybatis plus CU自動填充 和 軟刪除自動填充的實現方法

mybatis plus CU自動填充 和 軟刪除自動填充的實現方法

2021-10-08 10:46myEsn2E9''''s Notepad Java教程

這篇文章主要介紹了mybatis plus CU自動填充 和 軟刪除自動填充的實現方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

說明

CU 是 CRUD 中的創建和修改

本文實現以下需求效果

  • 創建數據時自動填充 createTime
  • 更新數據時自動填充 updateTime(每次修改都自動填充新的 updateTime 值)
  • 軟刪除數據時自動填充 deleteUserIddeleteTime

創建

實體類

為實體類(DO)的 createTime 字段配置以下 Annotation,代表標記在插入(insert into)時自動填充字段值

?
1
2
@TableField(fill = FieldFill.INSERT)
private Date createTime;

實現 MetaObjectHandler

如果實體(DO)中配置了上面的注解,就會執行這個 handler。這里在 insert 時自動填充 createTime 字段的值

?
1
2
3
4
5
6
7
8
9
10
11
12
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
    private static final String createTime = "createTime";
 
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, createTime, Date::new, Date.class);
        // 關于 is_delete 字段,這里不提供默認值,因為官方推薦設置數據庫中列的默認值
    }
 
    @Override
    public void updateFill(MetaObject metaObject) {}  
}

配置

注入 IOC 容器。
MybatisPlusMetaObjectHandler 類上配置 @Configuration 注解也可以達到同樣目的。

?
1
2
3
4
5
6
7
8
@Configuration
public class MybatisPlusConfig {
 
    @Bean
    public MybatisPlusMetaObjectHandler mybatisPlusCommonDateFieldValueFillHandler(){
        return new MybatisPlusMetaObjectHandler();
    }
}

更新

實體類

在實體類(DO)上配置注解

?
1
2
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;

實現 MetaObjectHandler

如果實體(DO)中配置了上面的注解,就會執行這個 handler。這里在 update 時自動填充 updateTime 字段的值

特別注意,這里需要重寫 strictFillStrategy 方法,因為默認的行為不會按照預期執行(每次更新數據時都更新 updateTime)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
    private static final String updateTime = "updateTime";
 
    @Override
    public void insertFill(MetaObject metaObject) {}
 
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, updateTime, Date::new, Date.class);
    }
 
    /**
     * 嚴格模式填充策略,默認有值不覆蓋,如果提供的值為null也不填充
     *
     * @param metaObject metaObject meta object parameter
     * @param fieldName  java bean property name
     * @param fieldVal   java bean property value of Supplier
     * @return this
     * @since 3.3.0
     */
    @Override
    public MetaObjectHandler strictFillStrategy(MetaObject metaObject, String fieldName, Supplier<?> fieldVal) {
        // 但當自動填充字段為 updateTime 時,始終更新它
        if (fieldName.equals(updateTime)) {
            Object obj = fieldVal.get();
            metaObject.setValue(fieldName, obj);
        } else if (metaObject.getValue(fieldName) == null) { // 這個 if 是源碼中的
            Object obj = fieldVal.get();
            if (Objects.nonNull(obj)) {
                metaObject.setValue(fieldName, obj);
            }
        }
        return this;
    }
}

配置

參考創建章節中的配置,如果已經配置了就不需要再配置了

軟刪除

配置 application.yml

?
1
2
3
4
5
6
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: is_delete # 邏輯刪除屬性名稱(為數據庫中的字段名稱)
      logic-delete-value: 1 # 代表已刪除的值
      logic-not-delete-value: 0 # 代表未刪除的值

實體類

在實體類(DO)中對以下字段配置注解。

標識 isDelete 字段作為邏輯刪除的標識,然后有兩個需要自動填充值的字段。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
  * 邏輯刪除標識
  *
  * \@TableLogic\ 注解標記邏輯刪除屬性
  */
@TableLogic
private Boolean isDelete;
 
@TableField(fill = FieldFill.UPDATE)
private Integer deleteUserId;
 
@TableField(fill = FieldFill.UPDATE)
private Date deleteTime;

重寫 DefaultSqlInjector

如果需要在軟刪除時自動填充其他字段的值,才需要重寫這個 DefaultSqlInjector,否則忽略本小節。

這里配置了邏輯刪除時填充其他字段值的 SqlInjector

?
1
2
3
4
5
6
7
8
9
10
public class MybatisPlusSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        final List<AbstractMethod> methods = super.getMethodList(mapperClass);
 
        methods.add(new LogicDeleteByIdWithFill());
 
        return methods;
    }
}

實現 MetaObjectHandler

由于 mybatis plus 的 @TableField 注解枚舉字段 fill 的值沒有我們想要的 Delete,所以 UpdateDelete 實際上都是走的 updateFill 函數,在函數內部我們需要區分出到底是更新還是軟刪除,才能繼續下一步即自動填充不同行為下字段的值

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
    private static final String deleteUserId = "deleteUserId";
    private static final String updateTime = "updateTime";
    private static final String deleteTime = "deleteTime";
 
    @Override
    public void insertFill(MetaObject metaObject) {}
 
    @Override
    public void updateFill(MetaObject metaObject) {
        // 有這兩個字段并且也已經 deleteUserId 有值(外面必須為實體類設置 deleteUserId 字段的值),deleteTime 外面不給值
        if (metaObject.hasGetter(deleteUserId)
                && metaObject.hasGetter(deleteTime)
                && !ObjectUtil.isNull(metaObject.getValue(deleteUserId))
                && ObjectUtil.isNull(metaObject.getValue(deleteTime))) {
            this.strictUpdateFill(metaObject, deleteUserId, () -> (Integer) metaObject.getValue(deleteUserId), Integer.class);
            this.strictUpdateFill(metaObject, deleteTime, Date::new, Date.class);
        } else {
            this.strictUpdateFill(metaObject, updateTime, Date::new, Date.class);
        }
    }
 
    /**
     * 嚴格模式填充策略,默認有值不覆蓋,如果提供的值為null也不填充
     *
     * @param metaObject metaObject meta object parameter
     * @param fieldName  java bean property name
     * @param fieldVal   java bean property value of Supplier
     * @return this
     * @since 3.3.0
     */
    @Override
    public MetaObjectHandler strictFillStrategy(MetaObject metaObject, String fieldName, Supplier<?> fieldVal) {
        // 但當自動填充字段為 updateTime 時,始終更新它
        if (fieldName.equals(updateTime)) {
            Object obj = fieldVal.get();
            metaObject.setValue(fieldName, obj);
        } else if (metaObject.getValue(fieldName) == null) { // 這個 if 是源碼中的
            Object obj = fieldVal.get();
            if (Objects.nonNull(obj)) {
                metaObject.setValue(fieldName, obj);
            }
        }
        return this;
    }
}

配置(注入到 IOC)

我們需要將上面寫的 MybatisPlusSqlInjector 注入 IOC 容器。

同樣的,這兩個 Bean 的配置,與在 MybatisPlusSqlInjectorMybatisPlusMetaObjectHandler 上配置 @Configuration 注解的效果一樣。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class MybatisPlusConfig {
 
    @Bean
    public MybatisPlusSqlInjector mybatisPlusSqlInjector(){
        return new MybatisPlusSqlInjector();
    }
 
    @Bean
    public MybatisPlusMetaObjectHandler mybatisPlusCommonDateFieldValueFillHandler(){
        return new MybatisPlusMetaObjectHandler();
    }
}

創建 MyBaseRepository

我這里將 Mapper 稱為 Repository。因為我用到了 MapStruct 庫,個人感覺它更適合被稱為 Mapper。

我們需要自己定義一個 MyBaseMapper 繼承自 BaseMapper(mybatis plus 的),然后添加一個如下的方法簽名,必須跟下面示例代碼一樣,因為我猜測內部是通過反射來調用的這個函數,所以方法簽名必須一致,否則無法被 mybatis plus 庫調用哦。

?
1
2
3
4
5
6
7
8
9
public interface MyBaseMapper<Entity>  extends BaseMapper<Entity> {
    /**
     * 邏輯刪除填充其他字段的值
     *
     * @param entity 要刪除的實體對象
     * @return 受影響記錄數量
     */
    int deleteByIdWithFill(Entity entity);
}

我們原來的 Repository 繼承自 mybatis plus 的 BaseMapper,現在我們需要修改為繼承自上面新寫的 MyBaseMapper。

創建 MyBaseService

因為我希望 XXXService 中也有 deleteByIdWithFill 函數,所以這里我還自定義了 Service 的基類,如果不需要的話可以忽略本小節。

自定義的 MyBaseService 繼承自 mybatis plus 的 IService<> 接口,然后添加如下方法簽名,注意方法簽名中的返回值是 boolean 而不是 int,因為寫 Service 需要方便外部使用。

?
1
2
3
4
5
6
7
8
9
public interface MyBaseService<Entity> extends IService<Entity> {
    /**
     * 邏輯刪除填充其他字段的值
     *
     * @param entity 要刪除的實體對象
     * @return 受影響記錄數量
     */
    boolean deleteByIdWithFill(Entity entity);
}

然后我們寫一個 MyBaseService 的實現類。

注意這里我們需要繼承自 mybatis plus 的 ServiceImpl 實現,減少我們自己實現的代碼量,同時還需要實現我們的 MyBaseService 接口,然后內部寫的巴巴適適的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MyBaseServiceImpl<EntityRepository extends MyBaseMapper<Entity>, Entity>
        extends ServiceImpl<EntityRepository, Entity>
        implements MyBaseService<Entity> {
    /**
     * 邏輯刪除填充其他字段的值
     *
     * @param entity 要刪除的實體對象
     * @return 受影響記錄數量
     */
    @Override
    public boolean deleteByIdWithFill(Entity entity) {
         return SqlHelper.retBool(getBaseMapper().deleteByIdWithFill(entity));
    }
}

最后,原來的 XXXService 修改為繼承自新寫的 MyBaseService,XXXServiceImpl 修改為繼承自新寫的 MyBaseServiceImpl

?
1
2
3
4
5
public interface TestService extends MyBaseService<Test> {}
 
@Service
public class TestServiceImpl extends MyBaseServiceImpl<TestRepository, Test>
implements TestService{}

食用

Controller 中的使用方法

?
1
2
3
4
5
6
7
8
9
10
11
12
@PostMapping("delete")
public ResponseEntity<?> delete(@Valid @NotNull(message = CommonRule.error.whenParamNull) @RequestBody TestTestDeleteBodyVo body) {
    final Test test = testService.getById(body.getId());
    if (test == null) {
        return ResponseEntity.ok().build();
    }
 
    test.setDeleteUserId(StpUtil.getLoginIdAsInt()); // 必須在軟刪之前設置 deleteUserId 字段的值
    testService.deleteByIdWithFill(test); // 軟刪除必須是這樣刪除
 
    return ResponseEntity.ok().build();
}

到此這篇關于mybatis plus CU自動填充 和 軟刪除自動填充的文章就介紹到這了,更多相關mybatis plus自動填充內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

原文鏈接:https://www.cnblogs.com/myesn/p/mybatis-plus-auto-fill-field-value-and-soft-delete.html

延伸 · 閱讀

精彩推薦
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
主站蜘蛛池模板: 亚洲国产天堂久久综合网站 | 国语刺激对白勾搭视频在线观看 | 精品视频一区二区三区 | 国产大片网站 | 性欧美video| 色噜噜狠狠色综合 | sao虎影院桃红视频在线观看 | 成年视频在线观看 | 农村妇女野战bbxxx农村妇女 | 国产成人精品一区二区 | 成人精品mv视频在线观看 | 亚洲精品综合一区二区 | 男女刺激高清视频在线观看 | 国产成人亚洲综合网站不卡 | 冰雪奇缘1完整版免费观看 变形金刚第一部 | 日韩高清成人毛片不卡 | 免费在线观看中文字幕 | 麻豆网站在线免费观看 | 91东航翘臀女神在线播放 | 国产欧美日韩不卡 | 欧美大b| 国语自产拍在线观看7m | 99精品国产成人一区二区在线 | 色图18p| 欧美激情 亚洲 | 男人天堂久久 | 激情自拍网 | 国产亚洲福利一区二区免费看 | 日本大尺度激情做爰叫床 | 白丝爆动漫羞羞动漫网站 | 91制片厂制作果冻传媒八夷 | a级片在线观看免费 | 成人欧美一区二区三区 | 四虎影院在线免费观看 | 99福利影院 | 色综合久久98天天综合 | 99久久精品免费观看区一 | 亚洲四虎在线 | 黑人与欧洲女子性大战 | narutotsunade全彩雏田 | 三上悠亚久久国产 |