자바생
article thumbnail
728x90

0.1. 쿼리 메서드란

1.

  • repository interface에 선언되는 DB에서 정보를 찾는 메서드

 

1.1. spring data JPA가 제공하는 쿼리 메서드 기능

2.

3.

  • 메서드 이름으로 쿼리 생성
  • 메서드 이름으로 JPA NamedQuery 호출
  • @Query 어노테이션을 사용하여 repository interface에 쿼리 직접 정의

 

3.0.1. 메서드 이름으로 쿼리 생성

  • spring data jpa를 사용하지 않는다면 작성해야할 JPQL
<code />
public List<Member> findByUsernameAndAge(String username, int age) { return em.createQuery( "select m from Member m" + " where m.username = :username" + " and m.age = :age", Member.class) .setParameter("age", age) .setParameter("username", username) .getResultList(); }
<java />
@Test void findByUsernameAndAge() throws Exception { //given Member m1 = new Member("AAA", 10); Member m2 = new Member("AAA", 20); memberJpaRepository.save(m1); memberJpaRepository.save(m2); //when List<Member> result = memberJpaRepository.findByUsernameAndAge("AAA", 10); //then assertThat(result.get(0)).isEqualTo(m1); }

  • 위 코드를 작성하면 사진과 같은 쿼리가 나가게 된다(당연한 결과)
  • 하지만 여기서 spring data jpa가 제공하는 "메서드 이름으로 쿼리 생성"을 사용해보자
<java />
List<Member> findByUsernameAndAge(String username, int age);

 

3.0.2. 만약에 메서드 이름을 규칙에 따라 작성하지 않는다면?

<java />
List<Member> findByUsernameasdAndAge(String username, int age);

  • 애플리케이션을 실행하면 위와 같은 에러가 발생한다
  • 질문 : spring data jpa가 어떻게 알고 쿼리를 자동으로 작성해줄까?

 

3.0.3. 그 외 다른 쿼리 메서드

<java />
List<Member> findTop3By();

<sql />
select member0_.member_id as member_i1_0_, member0_.age as age2_0_, member0_.team_id as team_id4_0_, member0_.username as username3_0_ from member member0_ limit 3;
  • 해당 기능은 엔티티의 필드명이 변경되면 메서드 이름도 "함께 변경"해야한다

 

3.0.4. JPA NamedQuery

<java />
@NamedQuery( name="Member.findByUsername", query="select m from Member m where m.username = :username" ) public class Member {}
  • JPA를 직접 사용하여 Named 쿼리를 호출
<code />
public List<Member> findByUsername(String username) { return em.createNamedQuery("Member.findByUsername", Member.class) .setParameter("username", username) .getResultList(); }
  • spring data jpa를 사용하여 Named 쿼리 호출
<java />
public interface MemberRepository extends JpaRepository<Member, Long>{ @Query(name = "Member.findByUsername") List<Member> findByUsername(@Param("username") String username); }
  • Query 어노테이션을 생략하고도 Named 쿼리 호출할 수 있다
<java />
public interface MemberRepository extends JpaRepository<Member, Long>{ //@Query(name = "Member.findByUsername") List<Member> findByUsername(@Param("username") String username); }
  • 왜 가능할까?
  • 제네릭에서 해당 repository에 저장할 도메인은 Member로 정했다
  • 그러면 Member.findByUsername이라는 NameQuery를 먼저 찾는다
    • 즉, spring data jpa가 쿼리 메서드를 실행할 때 우선순위가 있다는 것을 의미한다
    • 첫번째로 해당 도메인에 있는 NamedQuery를 먼저 찾고,
    • 두번째로 NamedQuery가 없다면 처음에 배웠던 property 이름을 가지고 생성하는 메서드가 실행된다
    • 우선순위를 변경할 수 있다고 한다! 
      • keyword : query lookup strategies

 

3.0.5. @Query, 메서드에 쿼리 직접 정의

  • 실행할 메서드에 정적 쿼리를 직접 작성
    • 이름 없는 Named Query라고 할 수 있음
  • 애플리케이션 실행 시점에 문법 오류를 발견할 수 있음
    • 매우 큰 장점

<java />
public interface MemberRepository extends JpaRepository<Member, Long>{ @Query("select m from Member m where m.username = :username and m.age = :age") List<Member> findUser(@Param("username") String username, @Param("age") int age); }

 

3.0.6. @NamedQuery는 실무에서 잘 사용하지 않는다?

  • 강의에서 Named Query는 실제로 사용하지 않는다고 함
  • 복잡한 정적 쿼리는 마지막에 배웠던 "메서드에 쿼리 직접 정의"를 사용하고
  • 간단한 정적 쿼리는 처음에 배웠던 "메서드 이름으로 쿼리 생성"을 사용함

 

3.0.7. @Query를 이용하여 DTO 조회

빨강색은 MemberDto 클래스의 경로를 의미하고, 파랑색은 MemberDto의 생성자 형식을 의미한다.

 


4. REFERENCES

728x90

'Spring 강의 > Spring data JPA' 카테고리의 다른 글

@EntityGraph  (0) 2022.04.13
벌크 연산  (0) 2022.04.12
페이징과 정렬  (0) 2022.04.11
profile

자바생

@자바생

틀린 부분이 있다면 댓글 부탁드립니다~😀

검색 태그