跳到主要内容

逻辑删除

信息

在本文中,读者无法发现和全局过滤器相关的内容,这是因为逻辑删除所需要的过滤器是内置的,且被Jimmer隐藏起来了。

映射

逻辑删除也称软删除,表示并不真正从数据库中删除数据,而是通过隐藏数据来达到数据被删除的假象。这可以为误操作留下一次恢复的机会。

逻辑删除相关的实体映射,在映射篇/进阶映射/逻辑删除有非常详细的介绍,这里不再重复所有细节,仅做一个简要回顾

Book.java
@Entity
public interface Book {

@LogicalDeleted("true")
boolean isDeleted();

...省略其他代码...
}

使用

过滤聚合根

BookTable table = Tables.BOOK_TABLE;

List<Book> books = sqlClient
.createQuery(table)
.select(table)
.execute();

生成的SQL为

select
tb_1_.ID,
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE,
tb_1_.DELETED,
tb_1_.STORE_ID
from BOOK tb_1_
where
/* highlight-next-line */
tb_1_.DELETED <> ? /* true */

过滤关联对象

AuthorTable author = Tables.AUTHOR_TABLE;

List<Author> authors = sqlClient
.createQuery(author)
.select(
author.fetch(
Fetchers.AUTHOR_FETCHER
.allScalarFields()
.books(
Fetchers.BOOK_FETCHER
.allScalarFields()
)
)
)
.execute();

在未启用缓存的情况下,这会生成两条SQL

  • 查询聚合根

    select
    tb_1_.ID,
    tb_1_.FIRST_NAME,
    tb_1_.LAST_NAME,
    tb_1_.GENDER
    from AUTHOR tb_1_
  • 查询关联对象,应用逻辑删除过滤器

    select
    tb_2_.AUTHOR_ID,
    tb_1_.ID,
    tb_1_.NAME,
    tb_1_.EDITION,
    tb_1_.PRICE
    from BOOK tb_1_
    inner join BOOK_AUTHOR_MAPPING tb_2_
    on tb_1_.ID = tb_2_.BOOK_ID
    where
    tb_2_.AUTHOR_ID in (
    ? /* 1 */, ? /* 2 */, ? /* 3 */, ? /* 4 */, ? /* 5 */
    )
    and
    /* highlight-next-line */
    tb_1_.DELETED <> ? /* true */

忽略逻辑删除过滤器

BookTable table = Tables.BOOK_TABLE;

List<Book> books = sqlClient
.filters(cfg -> {
cfg.setBehavior(LogicalDeletedBehavior.IGNORED);
})
.createQuery(table)
.select(table)
.execute();
  • ❶ 在不影响当前sqlClient的前提下,调整过滤器配置,创建新的临时sqlClient

  • ❷ 忽略软删除标志

这次,生成的SQL不再包含

select
tb_1_.ID,
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE,
tb_1_.DELETED,
tb_1_.STORE_ID
from BOOK tb_1_

反转逻辑删除过滤器

BookTable table = Tables.BOOK_TABLE;

List<Book> books = sqlClient
.filters(cfg -> {
cfg.setBehavior(LogicalDeletedBehavior.REVERSED);
})
.createQuery(table)
.select(table)
.execute();
  • ❶ 在不影响当前sqlClient的前提下,调整过滤器配置,创建新的临时sqlClient

  • ❷ 反转软删除标志,即查询被删除的数据

再次执行,生成的SQL为

生成的SQL为

select
tb_1_.ID,
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE,
tb_1_.DELETED,
tb_1_.STORE_ID
from BOOK tb_1_
where
/* highlight-next-line */
tb_1_.DELETED = ? /* true */

这次过滤条件为tb_1_.DELETED = true,即查询已经被删除数据,和默认的过滤规则刚好相反。