欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis-Flex 邏輯刪除的用法小結(jié)

 更新時(shí)間:2025年02月14日 09:56:48   作者:水w  
本文主要介紹了MyBatis-Flex 邏輯刪除的用法小結(jié),主要介紹了@Column注解使用及UpdateChain工具類介紹,具有一定的參考價(jià)值,感興趣的可以了解一下

一、@Column

MyBatis-Flex 提供了 @Column 用來對(duì)字段進(jìn)行更多的配置,以下是 @Column 的代碼定義:

public @interface Column {

    /**
     * 字段名稱
     */
    String value() default "";

    /**
     * 是否忽略該字段,可能只是業(yè)務(wù)字段,而非數(shù)據(jù)庫對(duì)應(yīng)字段
     */
    boolean ignore() default false;

    /**
     * insert 的時(shí)候默認(rèn)值,這個(gè)值會(huì)直接被拼接到 sql 而不通過參數(shù)設(shè)置
     */
    String onInsertValue() default "";

    /**
     * update 的時(shí)候自動(dòng)賦值,這個(gè)值會(huì)直接被拼接到 sql 而不通過參數(shù)設(shè)置
     */
    String onUpdateValue() default "";

    /**
     * 是否是大字段,大字段 APT 不會(huì)生成到 DEFAULT_COLUMNS 里
     */
    boolean isLarge() default false;

    /**
     * 是否是邏輯刪除字段,一張表中只能存在 1 一個(gè)邏輯刪除字段
     * 邏輯刪除的字段,被刪除時(shí),會(huì)設(shè)置為 1,正常狀態(tài)為 0
     */
    boolean isLogicDelete() default false;

    /**
     * 是否為樂觀鎖字段,若是樂觀鎖字段的話,數(shù)據(jù)更新的時(shí)候會(huì)去檢測(cè)當(dāng)前版本號(hào),若更新成功的話會(huì)設(shè)置當(dāng)前版本號(hào) +1
     * 只能用于數(shù)值的字段
     */
    boolean version() default false;

    /**
     * 配置的 jdbcType
     */
    JdbcType jdbcType() default JdbcType.UNDEFINED;

    /**
     * 自定義 TypeHandler
     */
    Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;

}

二、邏輯刪除相關(guān)場景

通過@Column設(shè)置字段邏輯刪除

邏輯刪除指的是在刪除數(shù)據(jù)的時(shí)候,并非真正的去刪除,而是將表中列所對(duì)應(yīng)的狀態(tài)字段(status)做修改操作, 實(shí)際上并未刪除目標(biāo)數(shù)據(jù)。

我們可以進(jìn)行表的字段設(shè)計(jì)時(shí),用一個(gè)列標(biāo)識(shí)該數(shù)據(jù)的 "刪除狀態(tài)",在 mybatis-flex 中,正常狀態(tài)的值為 0, 已刪除 的值為 1(可以通過設(shè)置 FlexGlobalConfig 來修改這個(gè)值)。

@Column(isLogicDelete = true)
private int isDeleted;

/*
對(duì)應(yīng)數(shù)據(jù)庫的表結(jié)構(gòu)中為:
is_deleted tinyint(1) default 0 numm comment '是否已邏輯刪除 0-否 1-是';
*/

當(dāng) "tb_account" 的數(shù)據(jù)被刪除時(shí)( is_delete = 1 時(shí)),我們通過 MyBatis-Flex 的 selectOneById 去查找數(shù)據(jù)時(shí),會(huì)查詢不到數(shù)據(jù)。 原因是 selectOneById 會(huì)自動(dòng)添加上 is_delete = 0 條件,執(zhí)行的 sql 如下:

SELECT * FROM tb_account where id = ? and is_delete = 0

不僅僅是 selectOneById 方法會(huì)添加 is_delete = 0 條件,BaseMapper 的以下方法也都會(huì)添加該條件:

  • selectOneBy**
  • selectListBy**
  • selectCountBy**
  • paginate

同時(shí),比如 Left Join 或者子查詢等,若 子表也設(shè)置了邏輯刪除字段, 那么子表也會(huì)添加相應(yīng)的邏輯刪除條件,例如:

QueryWrapper query1 = QueryWrapper.create()
    .select()
    .from(ACCOUNT)
    .leftJoin(ARTICLE).as("a").on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID))
    .where(ACCOUNT.AGE.ge(10));
/*
其執(zhí)行的 SQL 如下:
SELECT *
FROM `tb_account`
         LEFT JOIN `tb_article` AS `a`
         ON `a`.`is_delete` = 0 and `tb_account`.`id` = `a`.`account_id`
WHERE `tb_account`.`age` >= 10
  AND `tb_account`.`is_delete` = 0
*/

在 left join on 條件自動(dòng)添加a.is_delete = 0,并在 where 條件添加上 tb_account.is_delete = 0。

在邏輯刪除的基礎(chǔ)上,自動(dòng)更新更新時(shí)間update_time

(1)數(shù)據(jù)填充指的是,當(dāng) Entity 數(shù)據(jù)被插入或者更新的時(shí)候,會(huì)為字段進(jìn)行一些默認(rèn)的數(shù)據(jù)設(shè)置。這個(gè)非常有用,比如當(dāng)某個(gè) entity 被插入時(shí)候 會(huì)設(shè)置一些數(shù)據(jù)插入的時(shí)間、數(shù)據(jù)插入的用戶 id,多租戶的場景下設(shè)置當(dāng)前租戶信息等等。

MyBatis-Flex 提供了兩種方式,幫助開發(fā)者進(jìn)行數(shù)據(jù)填充。

  • 通過 @Table 注解的 onInsert  和 onUpdate配置進(jìn)行操作。 
  • 通過 @Column  注解的 onInsertValue  和 onUpdateValue配置進(jìn)行操作。 

@Table的注解和@Column注解的填充有什么區(qū)別?

  • @Table 注解的 onInsert 主要是在 Java 應(yīng)用層面進(jìn)行數(shù)據(jù)設(shè)置。 
  • @Column 注解的 onInsertValue 則是在數(shù)據(jù)庫層面進(jìn)行數(shù)據(jù)設(shè)置。

首先,需要在后端項(xiàng)目的model實(shí)體類中,通過注解配置將該類的對(duì)象屬性createTime和updateTime,映射到數(shù)據(jù)庫表中的特定字段create_time和update_time的默認(rèn)值設(shè)置等信息。

@Column(onInsertValue = "now()")
private Date createTime;

@Column(onUpdateValue = "now()", onInsertValue = "now()")
private Date updateTime;

@Column(isLogicDelete = true)
private int isDeleted;

/*
對(duì)應(yīng)數(shù)據(jù)庫的表結(jié)構(gòu)中為:
create_time timestamp null comment '創(chuàng)建時(shí)間';
update_time timestamp null comment '更新時(shí)間';
is_deleted tinyint(1) default 0 numm comment '是否已邏輯刪除 0-否 1-是';
*/

其中,onInsertValue表示當(dāng)數(shù)據(jù)被更新時(shí),設(shè)置的默認(rèn)值。onInsertValue配置的內(nèi)容 "now()" 會(huì)直接參與 SQL 的賦值拼接。而onUpdateValue表示當(dāng)數(shù)據(jù)被更新時(shí),設(shè)置的默認(rèn)值。onUpdateValue配置的內(nèi)容 "now()" 會(huì)直接參與 SQL 的賦值拼接。

在 insert 中,onInsertValue 配置的內(nèi)容會(huì)直接參與 SQL 拼接,而不是通過 JDBC 的 Statement 參數(shù)設(shè)置,需要開發(fā)者注意 onInsertValue 的內(nèi)容,否則可能會(huì)造成 SQL 錯(cuò)誤。

(2)UpdateChain 是一個(gè)對(duì) UpdateEntity、UpdateWrapper 等進(jìn)行封裝的一個(gè)工具類,方便用戶用于進(jìn)行鏈?zhǔn)讲僮鳌?/p>

假設(shè)我們要更新 Account 的 userName 為 "張三",更新年齡在之前的基礎(chǔ)上加 1,更新代碼如下:

@Test
public void testUpdateChain() {
    UpdateChain.of(Account.class)
        .set(Account::getUserName, "張三")
        .setRaw(Account::getAge, "age + 1")
        .where(Account::getId).eq(1)
        .update();
}

/*
以上方法調(diào)用時(shí),MyBatis-Flex 內(nèi)部執(zhí)行的 SQL 如下:
sql
UPDATE `tb_account` SET `user_name` = '張三' , `age` = age + 1
WHERE `id` = 1
*/

經(jīng)過測(cè)試之后,發(fā)現(xiàn)dataMapper.deleteBatchById(idsList)似乎不會(huì)自動(dòng)更新時(shí)間update_time,不知道為什么。不是說當(dāng)調(diào)用 deleteBatchById()方法時(shí),MyBatis-Flex 會(huì)根據(jù)實(shí)體類信息和注解配置,動(dòng)態(tài)生成一條更新語句,而不是刪除語句嗎??按道理來說,更新語句不應(yīng)該會(huì)觸發(fā)更新時(shí)間update_time字段的自動(dòng)更新嗎?(沒搞明白。。)

因此,可以通過MyBatis-Flex 提供的鏈?zhǔn)讲僮鞣绞?,來替換掉基礎(chǔ)的deletedById()方法。 

// dataMapper.deleteBatchByIds(idsList);
UpdateChain.of(dataMapper)
	.set(DataModel::getIsDeleted, 1)
	.where(DataModel::getIsDeleted, 0)
	.and(DataModel::getId).in(idsList)
	.update();

這樣MyBatis-Flex框架就會(huì)走更新語句的流程,數(shù)據(jù)庫表中就可以完成自動(dòng)更新update_time更新時(shí)間字段了。

跳過邏輯刪除處理

在某些場景下,比如說需要構(gòu)建回收站功能,那我們?cè)趫?zhí)行查詢、更新或刪除數(shù)據(jù)時(shí),有必要跳過 MyBatis-Flex 自動(dòng)添加的邏輯刪除的相關(guān)條件。

此時(shí),我們可以使用 LogicDeleteManager.execWithoutLogicDelete() 方法處理。這種方法在需要對(duì)所有數(shù)據(jù)進(jìn)行操作時(shí)非常有用,比如批量導(dǎo)出數(shù)據(jù)、進(jìn)行數(shù)據(jù)恢復(fù)等場景。

LogicDeleteManager 是一個(gè)用于處理邏輯刪除的管理器。execWithoutLogicDelete() 方法的作用是在執(zhí)行某些操作時(shí)忽略邏輯刪除的規(guī)則。這意味著,當(dāng)使用這個(gè)方法執(zhí)行查詢、插入、更新或刪除操作時(shí),系統(tǒng)不會(huì)考慮邏輯刪除標(biāo)志,即會(huì)處理所有數(shù)據(jù),包括那些被標(biāo)記為已刪除的數(shù)據(jù)。

比如,

LogicDeleteManager.execWithoutLogicDelete(()->
        accountMapper.deleteById(1)
        );

以上代碼中,accountMapper 會(huì)直接對(duì) Account 數(shù)據(jù)進(jìn)行物理刪除,忽略邏輯刪除字段配置。

代碼如下:

LogicDeleteManager.execWithoutLogicDelete(()->{
	// 此處寫邏輯
	UpdateChain.of(dataMapper)
	.set(DataModel::getIsDeleted, 0)
	.where(DataModel::getIsDeleted, 1)
	.and(DataModel::getId).in(idsList)
	.update();
	});

上述代碼中,UpdateChain.of(dataMapper) 創(chuàng)建了一個(gè)數(shù)據(jù)映射器對(duì)象dataMapper的更新鏈對(duì)象。.set(DataModel::getIsDeleted, 0) 設(shè)置 DataModel 的 isDeleted 字段值為 0,表示未刪除狀態(tài)。.where(DataModel::getIsDeleted, 1) 指定更新條件之一是isDeleted 字段值為 1,即邏輯上已被刪除的數(shù)據(jù)。.and(DataModel::getId).in(idsList) 添加額外的條件:id 字段的值必須在 idsList 列表中。.update() 執(zhí)行更新操作。

這段代碼的目的是在邏輯刪除被忽略的情況下,將指定 id 的數(shù)據(jù)從邏輯刪除狀態(tài)恢復(fù)到未刪除狀態(tài)。具體來說,只有那些 isDeleted 字段值為 1 并且 id 在 idsList 中的數(shù)據(jù)才會(huì)被更新。更新后,這些數(shù)據(jù)的 isDeleted 字段值會(huì)被設(shè)置為 0,表示這些數(shù)據(jù)不再被視為已刪除。

到此這篇關(guān)于MyBatis-Flex 邏輯刪除的用法小結(jié)的文章就介紹到這了,更多相關(guān)MyBatis-Flex 邏輯刪除內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 讀取PDF中的文本和圖片的方法

    Java 讀取PDF中的文本和圖片的方法

    本文將介紹通過Java程序來讀取PDF文檔中的文本和圖片的方法。分別調(diào)用方法extractText()和extractImages()來讀取,需要的朋友可以參考下
    2019-07-07
  • Java 調(diào)用Restful API接口的幾種方式(HTTPS)

    Java 調(diào)用Restful API接口的幾種方式(HTTPS)

    這篇文章主要介紹了Java 調(diào)用Restful API接口的幾種方式(HTTPS),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • @SpringBootApplication注解的使用

    @SpringBootApplication注解的使用

    這篇文章主要介紹了@SpringBootApplication注解的使用,幫助大家更好的理解和學(xué)習(xí)使用springboot框架,感興趣的朋友可以了解下
    2021-04-04
  • Spring探秘之如何妙用BeanPostProcessor

    Spring探秘之如何妙用BeanPostProcessor

    BeanPostProcessor也稱為Bean后置處理器,它是Spring中定義的接口,在Spring容器的創(chuàng)建過程中會(huì)回調(diào)BeanPostProcessor中定義的兩個(gè)方法,這篇文章主要給大家介紹了關(guān)于Spring探秘之如何妙用BeanPostProcessor的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • 在SpringBoot中使用JWT的實(shí)現(xiàn)方法

    在SpringBoot中使用JWT的實(shí)現(xiàn)方法

    這篇文章主要介紹了在SpringBoot中使用JWT的實(shí)現(xiàn)方法,詳細(xì)的介紹了什么是JWT和JWT實(shí)戰(zhàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • Spring?Cloud微服務(wù)架構(gòu)Sentinel數(shù)據(jù)雙向同步

    Spring?Cloud微服務(wù)架構(gòu)Sentinel數(shù)據(jù)雙向同步

    這篇文章主要為大家介紹了Spring?Cloud微服務(wù)架構(gòu)Sentinel數(shù)據(jù)雙向同步示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 簡單談?wù)凧ava中的棧和堆

    簡單談?wù)凧ava中的棧和堆

    堆和棧都是Java用來在RAM中存放數(shù)據(jù)的地方,下面這篇文章主要給大家介紹了關(guān)于Java中棧和堆的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-11-11
  • Mybatis 查詢語句條件為枚舉類型時(shí)報(bào)錯(cuò)的解決

    Mybatis 查詢語句條件為枚舉類型時(shí)報(bào)錯(cuò)的解決

    這篇文章主要介紹了Mybatis 查詢語句條件為枚舉類型時(shí)報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析

    Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析

    這篇文章主要介紹了Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • MyBatis實(shí)現(xiàn)字段加解密的實(shí)踐

    MyBatis實(shí)現(xiàn)字段加解密的實(shí)踐

    為了數(shù)據(jù)安全問題,有時(shí)候需要將部分敏感字段加密后再入庫,本文主要介紹了MyBatis實(shí)現(xiàn)字段加解密的實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11

最新評(píng)論