[spring] SpringData : “delete by”가 지원됩니까?

데이터베이스 액세스를 위해 Spring JPA를 사용하고 있습니다. 메서드 구현을 작성할 필요가없는 findByName 및 countByName과 같은 예제를 찾을 수 있습니다. 일부 조건에 따라 레코드 그룹을 삭제하는 예제를 찾고 싶습니다.

Spring JPA는 deleteByName과 같은 삭제를 지원합니까? 어떤 포인터라도 감사합니다.

감사합니다.



답변

Deprecated answer (Spring Data JPA <= 1.6.x) :

@Modifying구조에 대한 주석. 하지만 사용자 지정 SQL 동작을 제공해야합니다.

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

최신 정보:

현대 스프링 데이터 JPA (> = 1.7.x 이상)에 대한 쿼리 유도의 버전 delete, removecount작업에 액세스 할 수 있습니다.

public interface UserRepository extends CrudRepository<User, Long> {

    Long countByFirstName(String firstName);

    Long deleteByFirstName(String firstName);

    List<User> removeByFirstName(String firstName);

}


답변

지정된 메서드 이름을 사용한 삭제 쿼리 파생은 SpringData JPA 버전 1.6.0.RC1 부터 지원됩니다 . remove및 키워드 delete가 지원됩니다. 반환 값으로 제거 된 항목의 수 또는 목록 중에서 선택할 수 있습니다.

Long removeByLastname(String lastname);

List<User> deleteByLastname(String lastname);


답변

SpringData JPA의 소스 코드, 특히 PartTreeJpaQuery클래스를 살펴보면 인스턴스화를 시도하는 것을 볼 수 PartTree있습니다. 해당 클래스 내에서 다음 정규식

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

허용되는 것과 허용되지 않는 것을 나타내야합니다.

물론 이러한 메서드를 추가하려고하면 실제로 작동하지 않고 전체 스택 트레이스를 얻을 수 있습니다.

1.5.0.RELEASESpringData JPA 버전 을 사용하고 있음을 유의해야합니다.


답변

2 가지 방법 :-

첫 번째 맞춤 검색어

@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

그런 다음 목록에로드 한 다음 삭제 ID를 하나씩 호출합니다.

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

먼저 객체 목록을 가져온 다음 for 루프를 사용하여 ID를 하나씩 삭제합니다.

하지만 첫 번째 옵션 (사용자 정의 쿼리)은

그것은 단지 하나의 쿼리 일뿐입니다. 값이 존재하는 모든 곳에서 삭제됩니다.

이 링크도 통과하십시오 https://www.baeldung.com/spring-data-jpa-deleteby


답변

Spring JPA에서 직접 제공하는 미리 정의 된 삭제 메서드를 사용하는 경우 프레임 워크에서 아래의 두 쿼리가 실행됩니다.

  • 먼저 delete query where 절과 함께 select query를 실행하여 데이터 (ID 및 기타 컬럼 등)를 수집합니다.

  • 그런 다음 첫 번째 쿼리의 resultSet을 얻은 후 모든 ID에 대해 두 번째 삭제 쿼리가 실행됩니다 (하나씩)

    참고 : 단일 MYSQL 삭제 쿼리에 대해 많은 쿼리가 실행되기 때문에 이것은 응용 프로그램에 최적화 된 방법이 아닙니다.

이는 아래 사용자 정의 된 방법을 사용하여 하나의 삭제 쿼리 만 실행되기 때문에 쿼리 코드 삭제를위한 또 다른 최적화 된 방법입니다.



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


답변

일괄 삭제에 파생 쿼리를 사용할 때는주의하십시오. 예상 한 것이 아닙니다 : DeleteExecution


답변

예, deleteBy 메서드가 지원됩니다. 사용하려면 @Transactional로 메서드에 주석을 달아야합니다.