Other Methods, Modifying Queries

2024. 10. 24. 16:05·Spring Boot/Spring Data JPA

https://sundaland.tistory.com/419

 

[ ▶ Other Methods ]

Spring Data JPA는 다양한 방법으로 쿼리를 작성할 수 있는 기능을 제공한다. 그러나 때때로 쿼리가 제공된 기술로는 너무 복잡할 수 있다. 이런 경우에는 다음과 같은 대안들을 고려해볼 수 있다.

 

[ ▷ 직접 쿼리 작성하기 ]

가장 먼저 고려해야 할 방법은 @Query 어노테이션을 사용하여 직접 쿼리를 작성하는 것이다. 이를 통해 JPQL, HQL, 또는 네이티브 SQL을 사용하여 원하는 대로 쿼리를 구성할 수 있다.

public interface UserRepository extends JpaRepository<User, Long> {

  @Query("SELECT u FROM User u WHERE u.lastname = ?1")
  List<User> findByLastname(String lastname);
}

이와 같이 쿼리를 직접 작성하면, 쿼리가 복잡하더라도 원하는 결과를 얻을 수 있다.

 

[ ▷ 커스텀 구현체 만들기 ]

직접 쿼리를 작성하는 것이 충분하지 않거나 더 복잡한 로직이 필요한 경우, 커스텀 구현을 고려할 수 있다. 이를 통해 레포지토리에 메서드를 등록하면서 구현은 전적으로 사용자에게 맡길 수 있다.

이렇게 하면 다음과 같은 기능을 활용할 수 있다.

  • EntityManager 직접 사용: 순수 HQL, JPQL, EQL, 네이티브 SQL을 작성하거나 Criteria API를 사용할 수 있다.
  • Spring Framework의 JdbcTemplate 활용: 네이티브 SQL을 작성하여 데이터베이스와 직접 상호작용할 수 있다.
  • 타사 데이터베이스 툴킷 사용: 특정 데이터베이스나 ORM에 특화된 툴킷을 사용할 수 있다.

커스텀 리포지토리 구현을 통해 복잡한 쿼리를 작성할 수 있다.

public class UserRepositoryImpl implements UserRepositoryCustom {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<User> customQueryMethod() {
        String jpql = "SELECT u FROM User u WHERE u.age > :age";
        return entityManager.createQuery(jpql, User.class)
                            .setParameter("age", 18)
                            .getResultList();
    }
}

 

[ ▷ 데이터베이스 내장 쿼리 사용하기 ]

쿼리를 데이터베이스에 저장하고 싶다면, @StoredProcedure 어노테이션을 사용하여 저장 프로시저를 호출하거나, 데이터베이스 함수에 대해 @Query 어노테이션을 사용하고 CALL로 호출할 수 있다.

예를 들어, 저장 프로시저를 호출하는 방법은 다음과 같다.

public interface UserRepository extends JpaRepository<User, Long> {

    @Modifying
    @Procedure(name = "my_procedure")
    void callMyProcedure();
}

이러한 방법들은 최대한의 쿼리 제어를 필요로 할 때 유용하며, Spring Data JPA가 제공하는 자원 관리 기능을 유지하면서도 더 복잡한 로직을 구현할 수 있게 해준다. 각 방법의 사용은 필요에 따라 선택할 수 있으며, 복잡한 쿼리 로직을 요구하는 비즈니스 요구사항에 맞게 조정할 수 있다.

 

[ ▶ Modifying Queries ]

pring Data JPA는 쿼리를 선언하여 엔티티나 엔티티 컬렉션에 접근하는 방법을 설명했다. 이제는 쿼리를 수정하는 사용자 정의 동작을 추가할 수 있는 방법에 대해 알아본다.

 

[ ▷ 수정 쿼리 선언하기 ]

수정 쿼리는 특정 엔티티의 속성을 업데이트하거나 삭제하는 쿼리다. 이를 위해 @Modifying 어노테이션을 사용해야 한다. 다음은 수정 쿼리의 예시다.

@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);

이와 같이 @Modifying을 사용하면 해당 쿼리가 선택 쿼리(selecting query)가 아닌 업데이트 쿼리로 처리된다.

 

[ ▷ EntityManager와의 관계 ]

수정 쿼리를 실행한 후에는 EntityManager가 오래된 엔티티를 포함할 수 있다. Spring Data JPA는 EntityManager.clear()를 자동으로 호출하지 않는다. 이는 여전히 플러시되지 않은 변경 사항을 모두 삭제하기 때문이다. 만약 EntityManager를 자동으로 지우고 싶다면, @Modifying 어노테이션의 clearAutomatically 속성을 true로 설정할 수 있다.

 

[ ▷ 파생 삭제 쿼리 ]

Spring Data JPA는 파생 삭제 쿼리를 지원하여 JPQL 쿼리를 명시적으로 선언하지 않고도 삭제 작업을 수행할 수 있다. 다음은 파생 삭제 쿼리의 예시다.

interface UserRepository extends Repository<User, Long> {

  void deleteByRoleId(long roleId);

  @Modifying
  @Query("delete from User u where u.role.id = ?1")
  void deleteInBulkByRoleId(long roleId);
}

deleteByRoleId(long roleId) 메서드는 기본적으로 deleteInBulkByRoleId(long roleId)와 유사한 결과를 생성하는 것처럼 보인다. 그러나 두 메서드 선언 사이에는 중요한 차이가 있다.

  • deleteInBulkByRoleId(...) 메서드는 주어진 JPQL 쿼리를 데이터베이스에 단일 쿼리로 발행한다. 이로 인해 현재 로드된 User 인스턴스는 생명주기 콜백(lifecycle callbacks)을 호출하지 않는다.
  • 반면에 deleteByRoleId(...)는 쿼리를 실행한 후 결과를 하나씩 삭제하여 영속성 제공자가 해당 엔티티에서 @PreRemove 콜백을 실제로 호출할 수 있도록 한다.


파생 삭제 쿼리는 쿼리를 실행한 후 CrudRepository.delete(Iterable users) 메서드를 호출하여 엔티티를 삭제하는 방법의 단축키 역할을 한다. 이를 통해 CRUD 연산의 일관성을 유지하면서 더 간결하게 쿼리를 작성할 수 있다. 수정 쿼리와 삭제 쿼리를 효과적으로 활용하면, 복잡한 비즈니스 로직을 간단하게 처리할 수 있다.

'Spring Boot > Spring Data JPA' 카테고리의 다른 글

Scrolling  (0) 2024.10.24
Using @Query  (0) 2024.10.24
Using Sort, Scrolling Large Query Results  (0) 2024.10.24
Using JPA Named Queries  (0) 2024.10.24
Query Lookup Strategies  (0) 2024.10.24
  1. [ ▶ Other Methods ]
  2. [ ▷ 직접 쿼리 작성하기 ]
  3. [ ▷ 커스텀 구현체 만들기 ]
  4. [ ▷ 데이터베이스 내장 쿼리 사용하기 ]
  5. [ ▶ Modifying Queries ]
  6. [ ▷ 수정 쿼리 선언하기 ]
  7. [ ▷ EntityManager와의 관계 ]
  8. [ ▷ 파생 삭제 쿼리 ]
'Spring Boot/Spring Data JPA' 카테고리의 다른 글
  • Scrolling
  • Using @Query
  • Using Sort, Scrolling Large Query Results
  • Using JPA Named Queries
GLaDiDos
GLaDiDos
GLaDiDos
GLaDiDos의 티스토리
GLaDiDos
전체
오늘
어제
  • 분류 전체보기 (207)
    • 자바 튜토리얼 (19)
    • 스프링 프레임워크 (15)
      • IoC (Inversion of Control) (7)
    • Toby Spring 3.1 (4)
    • 테스트 주도 개발 (TDD) (4)
    • 디자인 패턴 (1)
    • 깃 (Git) (1)
    • Reflection (10)
    • 스프링 AOP (15)
    • JPA (Java Persistence API) (10)
    • 네트워크 (5)
    • Spring Boot (48)
      • Annotations (3)
      • Auto-Configuration (12)
      • Spring Data JPA (28)
      • Spring Security (4)
    • Apache Tomcat (7)
    • Web on Servlet Stack (29)
    • 자바 (4)
    • 개인 코드 분석 (9)
    • Spring Security in Action (11)
    • AWS (Amazon Web Service) (2)
      • EC2 (2)
    • 도커 (Docker) (0)
    • 리눅스 (1)
    • 스프링 마이크로서비스 (8)
    • 마이크로서비스 아키텍처 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

링크

공지사항

인기 글

태그

최근 댓글

최근 글

hELLO· Designed By정상우.v4.6.1
GLaDiDos
Other Methods, Modifying Queries
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.