当前位置: 首页 > 知识库问答 >
问题:

使用Spring JPA处理软删除

秦哲瀚
2023-03-14

我有一个表东西定义为。。。

id, <fields>..., active

Active是软删除标志,始终为10。从长远来看,这可能会有利于历史性的谈判桌。

public interface StuffRepository extends JpaRepository<StuffEntity, Long> {} 

在代码中,我们总是使用活动记录。有没有办法让Spring总是在为这个存储库生成的查询中附加一个active=1条件?或者更理想地允许我扩展用于生成查询的语法?

我知道我可以在任何地方创建命名的@队列,但这样我就失去了生成查询的便利性。我还想避免用“主动”方法污染界面。

如果有必要的话,我将使用Hibernate 4.2作为我的JPA实现。


共有3个答案

雷晋
2023-03-14

基于易天明 答:我创建了Crudepository实现,其中包含用于软删除的重写方法:

@NoRepositoryBean
public interface SoftDeleteCrudRepository<T extends BasicEntity, ID extends Long> extends CrudRepository<T, ID> {
  @Override
  @Transactional(readOnly = true)
  @Query("select e from #{#entityName} e where e.isActive = true")
  List<T> findAll();

  @Override
  @Transactional(readOnly = true)
  @Query("select e from #{#entityName} e where e.id in ?1 and e.isActive = true")
  Iterable<T> findAll(Iterable<ID> ids);

  @Override
  @Transactional(readOnly = true)
  @Query("select e from #{#entityName} e where e.id = ?1 and e.isActive = true")
  T findOne(ID id);

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

  @Override
  @Transactional(readOnly = true)
  @Query("select count(e) from #{#entityName} e where e.isActive = true")
  long count();

  @Override
  @Transactional(readOnly = true)
  default boolean exists(ID id) {
      return findOne(id) != null;
  }

  @Override
  @Query("update #{#entityName} e set e.isActive=false where e.id = ?1")
  @Transactional
  @Modifying
  void delete(Long id);


  @Override
  @Transactional
  default void delete(T entity) {
      delete(entity.getId());
  }

  @Override
  @Transactional
  default void delete(Iterable<? extends T> entities) {
      entities.forEach(entitiy -> delete(entitiy.getId()));
  }

  @Override
  @Query("update #{#entityName} e set e.isActive=false")
  @Transactional
  @Modifying
  void deleteAll();
}

它可以与BasicEntity一起使用:

@MappedSuperclass
public abstract class BasicEntity {
  @Column(name = "is_active")
  private boolean isActive = true;

  public abstract Long getId();

  // isActive getters and setters...
}

最终实体:

@Entity
@Table(name = "town")
public class Town extends BasicEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "town_id_seq")
    @SequenceGenerator(name = "town_id_seq", sequenceName = "town_id_seq", allocationSize = 1)
    protected Long id;

    private String name;

    // getters and setters...
}
商天逸
2023-03-14

这是一个老问题,你可能已经找到了答案。但是,对于所有正在寻找答案的Spring/JPA/Hibernate程序员来说-

假设你有一只实体狗:

 @Entity
 public class Dog{

 ......(fields)....        

 @Column(name="is_active")
 private Boolean active;
 }

以及一个存储库:

public interface DogRepository extends JpaRepository<Dog, Integer> {
} 

您所需要做的就是在实体级别上添加@where注释,结果是:

@Entity
@Where(clause="is_active=1")
public class Dog{

......(fields)....        

@Column(name="is_active")
private Boolean active;
}

存储库执行的所有查询将自动过滤掉“非活动”行。

姬庆
2023-03-14

@Where(clause=“is_active=1”)不是用spring数据jpa处理软删除的最佳方式。

首先,它只适用于hibernate实现。

第二,永远不能用spring数据获取软删除的实体。

#{#entityName}表达式可用于表示具体实体类型名称的通用存储库。

代码会是这样的:

//Override CrudRepository or PagingAndSortingRepository's query method:
@Override
@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")
public List<T> recycleBin(); 

//Soft delete.
@Query("update #{#entityName} e set e.deleteFlag=true where e.id=?1")
@Modifying
public void softDelete(String id); 
 类似资料:
  • 问题内容: 我有一个表Stuff定义为… 活动状态是软删除标志,并且始终为1或0。从长远来看,这可能会取代历史表格。 在代码中,我们始终 使用活动记录。有什么方法可以让Spring始终active=1为该存储库生成的查询附加条件?或更理想的情况是允许我扩展用于生成查询的语法? 我知道可以在任何地方创建named ,但是随后我就失去了生成查询的便利。我还想避免使用“活动”方法污染接口。 如果重要的话

  • 我在删除联接表中引用的实体时遇到问题。以下是三个链接的enitie。 当我尝试使用CrudRepository从来宾表中删除来宾时,它会给我这个错误。 错误:表“guest”上的更新或删除违反了表“guest\u group\u join”上的外键约束“FKKOUGVMCU860MOUACR1SHJXY”。键(id)=(4)仍然从表“guest\u group\u join”中引用。 有人能帮忙吗

  • 问题内容: 我需要更新或删除几个文档。 当我更新时,我这样做: 我首先搜索文档,为返回的结果设置更大的限制(比方说,大小:10000)。 对于每个返回的文档,我都会修改某些值。 我不喜欢对整个修改后的清单(批量索引)进行Elasticsearch。 该操作一直进行到点1不再返回结果为止。 当我删除时,我这样做: 我首先搜索文档,为返回结果设置更大的限制(例如,大小:10000) 我删除所有找到的发

  • 我仍然是java和spring的初学者,我已经在mysql中存储了一个名为< code>Offers的表,我试图逐行获取数据< code >其中Status == 0,我的表看起来像这样: 当我尝试运行我的代码时,它的返回 org.springframework.beans.factory。BeanCreationException:创建在类路径资源[org/springframework/boo

  • 软删除 在实际项目中,对数据频繁使用删除操作会导致性能问题,软删除的作用就是把数据加上删除标记,而不是真正的删除,同时也便于需要的时候进行数据的恢复。 要使用软删除功能,需要引入SoftDelete trait,例如User模型按照下面的定义就可以使用软删除功能: <?php namespace app\index\model; use think\Model; use think\model\

  • 1. 前言 在 SQL Delete 一节中,我们介绍了 SQL 的基本删除功能,今天我们将以分类和实战的角度来进一步学习 SQL 的删除。 删除是一个很危险的操作,试想一下如果开发人员不慎操作失误,误删了一些数据,在数据未备份的情况下,该数据无法恢复,造成了损失绝对是致命的。 道路千万条,安全第一条。因此为了保证数据的安全性,在真正的企业级应用中都会默认的采用逻辑删除(软删除)的方式来处理数据删