如何在Spring Data JDBC中处理软删除?

4

在Spring Data JDBC中如何处理软删除?

在Spring Data JPA中,我们可以添加 @Where(clause="is_active=1") 注解或扩展 CrudRepositoryPagingAndSortingRepository

由于Spring Data JDBC不支持在查询中使用SPEL,因此我们不能以通用的方式编写查询,例如:

@NoRepositoryBean
public interface SoftDeleteCrudRepository<T extends BasicEntity, ID extends 
Long> extends CrudRepository<T, ID> {
//Override CrudRepository or PagingAndSortingRepository's query method:
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.deleteFlag=false")
public List<T> findAll();

//Look up deleted entities
@Query("select e from #{#entityName} e where e.deleteFlag=true")
@Transactional(readOnly = true)
public List<T> findAllDeleted(); 

//Soft delete.
@Query("update #{#entityName} e set e.deleteFlag=true where e.id=?1")
@Transactional
@Modifying
public void softDelete(String id);
...
}

那么扩展CrudRepositoryPagingAndSortingRepository是指为每个实体/表的每个存储库编写相同的查询吗?例如:

Repository1
@Override
@Transactional(readOnly = true)
@Query("select id, name, value, deleteFlag from table1 e where e.deleteFlag=false")
public List<T> findAll();
....

Repository2
@Override
@Transactional(readOnly = true)
@Query("select id, name, value, deleteFlag from table2 e where e.deleteFlag=false")
public List<T> findAll();
....

感谢您提前回复!

我定义了一个接口来实现这个功能,可以参考 mu.xufan 的回答 https://dev59.com/dGIk5IYBdhLWcg3wYtT7#54125203 - mu.xufan
我不认为在数据库中通过将 deleted_ind = true 而不是硬删除实体或仅检索 deleted_ind = false 的实体来删除实体是可行的,对于 findBy****findAll 方法。 - Dexter
2个回答

2

目前我看到有三种方法可以实现这个目标。

  1. 使用视图。为每个聚合根创建一个数据库视图,过滤掉软删除的行。将你的实体映射到这些视图。

  2. 编写自己的 SqlGenerator。并通过 SqlGeneratorSource 将其注入到 DefaultDataAccessStrategy 中。由于 SqlGenerator 只是包可见的,因此您需要基本上复制现有的 DefaultDataAccessStrategy 来创建自己的。当然,这将带来长期的维护成本。

  3. 由于您的场景似乎只需要实体名称的特殊 SpEL 支持,因此打开问题并提交拉取请求可能是一个可行的选项。如果您对此方法感兴趣并需要更多帮助,请在问题描述中提及。


-1

@Dexter,我们在数据库中使用INT类型来标记记录的活动状态。如果您使用布尔值,您可以修改StateTag枚举(也许接口更好),然后调用changeState来改变状态。 删除或禁用由业务服务层考虑,像这样:

public class RoleServiceImpl extends SoftDeleteRepositoryServiceImpl<Role, Long>
    implements RoleService {
    private static final Logger LOGGER = LoggerFactory.getLogger(RoleServiceImpl.class);

.......

@Override
public Role deleteRole(Long roleId) {
    return softDelete(roleId);
}

}

 public class SoftDeleteRepositoryServiceImpl<T, ID extends Serializable> extends BasicRepositoryServiceImpl<T, ID>
    implements SoftDeleteRepositoryService<T, ID> {


@Override
public T enable(ID id) {
    return updateState(id, ENABLED);
}

  ........

@Override
public T softDelete(ID id) {
    return updateState(id, DELETED);
}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接