• 함수 위에 @query("쿼리문 작성")와 같이 쿼리문을 작성하면 함수는 해당 쿼리문을 실행한 결과를 반환한다.
  • 이때 쿼리문을 작성할 때 객체 중심으로 작성이 된다.
  • 즉, UserInfo 클래스에 대응되는 user_info 테이블이 있을 때 쿼리문에서는 "... from UserInfo ..."와 같이 진행해줘야 한다.
  • @Query의 용도는 조회이다.
  • 또한, JPQL을 사용하면 자동으로 flush() 메소드를 호출한다. -> 정확히 말하면 query가 날아갈 때
    -> 자동으로 flush가 호출되는 경우는 영속성 컨텍스트에 JPQL에서 지정한 엔티티가 존재할 때만이다.
  • 마지막으로, JPQL을 사용하면 영속성 컨텍스트를 거치지 않고 DB에 쿼리를 바로 날리기 때문에 1차 캐시에 있는 내용과 DB에 있는 내용이 다를 수 있다.
    • 예를 들어 이미 1차 캐시에 조회한 엔티티가 있고, JPQL로 update를 실행까지 한 상황이라고 가정하자. 이때 다시 해당 엔티티를 조회하면 1차 캐시에 있는 엔티티를 조회하기 때문에 update 쿼리가 적용이 안 된 엔티티를 가져온다.
    • 따라서 이때는 영속성 컨텍스트를 clear()로 비워준다음에 DB로부터 조회하도록 해줘야 한다.
    • 기본적으로 조회할 때는 1차 캐시에 있으면 1차 캐시에서 가져오고, 없으면 DB에서 조회한 다음 1차 캐시에 싣기 때문이다.
    • flush() 메소드를 호출해도 1차 캐시를 비우지 않는다. clear()를 호출해야 1차 캐시를 비운다.
    • delete()의 경우에도 마찬가지로 영속성 컨텍스트에 아무런 동작을 시키지 않고 DB에 바로 쿼리가 날아간다.
    • 조회의 경우에도 바로 DB에 쿼리가 날아가지만, 조회 결과를 영속성 컨텍스트 1차 캐시에 저장한다. ( 이미 존재하면 1차 캐시에 있는 거 사용 )

참고

flush() 메소드를 호출해도 1차 캐시를 비우지 않는다. clear()를 호출해야 1차 캐시를 비운다.

 

@Modifying

  • @Query는 조회 용도로 쓰기 때문에, update나 delete 쿼리문의 경우에는 이 어노테이션을 붙여줘야 한다.
  • 이 어노테이션 같은 경우 flushAutomatically가 default 값으로 false여도 JPQL이므로 flush가 자동으로 호출된다.
  • 또한, clearAutomatically도 속성으로 가지고 있는데 default 값은 false이다.
  • 두 옵션 모두 굳이 건들 필요는 없을 거 같다. -> flush가 필요한데, flush를 안 할 때 사용하자. ( 사용할 일은 거의 없을 듯 )

+ Recent posts