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

时间:2018-12-30 18:28:42

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

在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();
....

感谢您的提前答复!

2 个答案:

答案 0 :(得分:2)

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

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

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

  3. 由于您所需要的只是为实体名称提供非常特殊的SpEL支持,因此可以为实体名称打开一个问题并提交拉取请求。如果您对此方法感兴趣,并且需要更多帮助,请在问题说明中予以提及。

答案 1 :(得分:0)

@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);
}
}