Spring Data: 支持“ delete by”吗?

我使用 SpringJPA 进行数据库访问。我能够找到诸如 findByName 和 CountByName 之类的示例,对于这些示例,我不需要编写任何方法实现。我希望找到一些例子,删除一组记录基于一些条件。

SpringJPA 是否支持与 delete teByName 类似的 delete? 任何指针都可以。

问候你,谢谢。

228426 次浏览

不推荐的回答(Spring Data JPA < = 1.6.x) :

您需要提供自定义的 SQL 行为。

public interface UserRepository extends JpaRepository<User, Long> {
@Modifying
@Query("delete from User u where u.firstName = ?1")
void deleteUsersByFirstName(String firstName);
}

更新:

在 Spring Data JPA (> = 1.7.x)的现代版本中,可以访问 deleteremovecount操作的查询派生。

public interface UserRepository extends CrudRepository<User, Long> {


Long countByFirstName(String firstName);


Long deleteByFirstName(String firstName);


List<User> removeByFirstName(String firstName);


}

如果您查看 Spring Data JPA 的源代码,特别是 PartTreeJpaQuery类,您将看到尝试实例化 PartTree。 在该类内部有以下正则表达式

private static final Pattern PREFIX_TEMPLATE = Pattern.compile("^(find|read|get|count|query)(\\p{Lu}.*?)??By")

应该指出什么是允许的,什么是不允许的。

当然,如果您尝试添加这样一个方法,您实际上会看到,这是不工作的,您得到完整的堆栈跟踪。

我应该指出,我使用的是 Spring Data JPA 的 1.5.0.RELEASE版本

Derivation of delete queries using given method name is supported starting with version 1.6.0.RC1 of Spring Data JPA. The keywords remove and delete are supported. As return value one can choose between the number or a list of removed entities.

Long removeByLastname(String lastname);


List<User> deleteByLastname(String lastname);

如果您使用 Spring JPA 直接提供的预定义删除方法,那么框架将执行以下两个查询。

  • 首先通过执行 select query 和 delete query where 子句收集数据(如 id 和其他列)。

  • 然后在获得第一个查询的 result 集之后,将对所有 id 执行第二个 delete 查询(一个接一个)

    Note : This is not optimized way for your application because many queries will be execute for single MYSQL delete query.

这是另一种优化的删除查询代码方法,因为只有一个删除查询将使用以下自定义方法执行。




@NamedNativeQueries({


@NamedNativeQuery(name = "Abc.deleteByCreatedTimeBetween",
query = "DELETE FROM abc WHERE create_time BETWEEN ?1 AND ?2")
,


@NamedNativeQuery(name = "Abc.getByMaxId",
query = "SELECT max(id) from abc")
})


@Entity
public class Abc implements Serializable {


}


@Repository
public interface AbcRepository extends CrudRepository {


int getByMaxId();


@Transactional
@Modifying
void deleteByCreatedTimeBetween(String startDate, String endDate);
}


2 ways:-

第一个自定义查询

@Modifying
@Query("delete from User where firstName = :firstName")
void deleteUsersByFirstName(@Param("firstName") String firstName);

第二个 JPA 方法查询

List<User> deleteByLastname(String lastname);

当您使用方法查询(第二种方式)时,它将首先执行一个 get 调用

select * from user where last_name = :firstName

然后它将把它装载到一个 List 中 然后它将逐个调用 delete id

delete from user where id = 18
delete from user where id = 19

首先获取对象列表,然后循环逐个删除 id

But, the 1st option (custom query),

It's just a single query 它将删除所有存在值的地方。

因为在第二个选项中它是多数据库查询,尝试使用第一个选项。

Go through this link too https://www.baeldung.com/spring-data-jpa-deleteby

是的,支持 delete teBy 方法 To use it you need to annotate method with @Transactional

以下是我的建议。你也可以使用本地查询,比如:

@Modifying
@Query(value="delete from rreo r where r.cod_ibge = ?1 and r.exercicio= ?2", nativeQuery = true)
void deleteByParameters(Integer codIbge, Integer exercicio);
@Query(value = "delete from addresses u where u.ADDRESS_ID LIKE %:addressId%", nativeQuery = true)
void deleteAddressByAddressId(@Param("addressId") String addressId);

它的工作原理

import org.springframework.transaction.annotation.Transactional;


@Transactional
Long removeAddressByCity(String city);