【问题标题】:How to handle soft-delete in Spring Data JDBC?如何处理 Spring Data JDBC 中的软删除?
【发布时间】:2019-05-27 13:32:54
【问题描述】:

在 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 回答stackoverflow.com/questions/19323557/…
  • 我看不到它如何通过在 DB 中设置 deleted_ind = true 来删除实体,而不是硬删除它,或者只检索带有 findBy****findAll 方法的 deleted_ind = false 实体

标签: java spring-data spring-data-jdbc


【解决方案1】:

我目前看到三种选择如何实现这一目标。

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

  2. 写你自己的SqlGenerator。并通过SqlGeneratorSource 将其注入DefaultDataAccessStrategy。由于SqlGenerator 仅对包可见,因此您必须创建自己的DefaultDataAccessStrategy,因为这基本上复制了现有的。当然,这会带来长期的维护成本。

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

【讨论】:

    【解决方案2】:

    @Dexter,我们在 db 中使用 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);
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-12-07
      • 1970-01-01
      • 1970-01-01
      • 2016-08-14
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 2018-10-08
      • 2017-10-04
      相关资源
      最近更新 更多