Member Class에 있는 Entity에다가 아래와 같이 작성을 해주고
@Entity
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "username", "age"})
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.username = :username"
)
MemberJpaRepositoryTest를 createNamedQuery를 이용해서 Member에서 정의한 걸 가지고 온다.
"Member.findByUsername"
// MemberJpaRepository class
public List<Member> findByUsername(String username) {
return em.createNamedQuery("Member.findByUsername", Member.class)
.setParameter("username", "회원12")
.getResultList();
}
"회원12"를 username으로 바꾼 후에
public List<Member> findByUsername(String username) {
return em.createNamedQuery("Member.findByUsername", Member.class)
.setParameter("username", username)
.getResultList();
}
MemberJpaRepositoryTest에서 아래와 같이 설정을 해주고 빌드를 돌리면 결과가 잘 나오게 된다.
@Test
public void testNamedQuery() {
Member m1 = new Member("AAA", 10);
Member m2 = new Member("BBB", 20);
memberJpaRepository.save(m1);
memberJpaRepository.save(m2);
List<Member> result = memberJpaRepository.findByUsername("AAA");
Member findMember = result.get(0);
assertThat(findMember).isEqualTo(m1);
}
select
member0_.member_id as member_i1_0_,
member0_.age as age2_0_,
member0_.tema_id as tema_id4_0_,
member0_.username as username3_0_
from
member member0_
where
member0_.username=?
MemberJpaRepositoryTest에서 @Param을 넘길 때가 있는데
package study.datajpa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import study.datajpa.entity.Member;
import java.util.List;
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
List<Member> findTop3HelloBy();
@Query(name = "Member.findByUsername")
List<Member> findByUsername(@Param("username") String username);
}
Member class 에서 JPQL을 명확히 작성했을 때 Named parameter로 넘어가야 할 때가 있다. 그 때 @Param annotation을 넘겨줘야 한다.
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.username = :username"
)
MemberRepositoryTest에서 빌드를 돌려보면 쿼리가 똑같이 나오는 것을 확인할 수 있다.
@Test
public void testNamedQuery() {
Member m1 = new Member("AAA", 10);
Member m2 = new Member("BBB", 20);
memberRepository.save(m1);
memberRepository.save(m2);
List<Member> result = memberRepository.findByUsername("AAA");
Member findMember = result.get(0);
assertThat(findMember).isEqualTo(m1);
}
select
member0_.member_id as member_i1_0_,
member0_.age as age2_0_,
member0_.tema_id as tema_id4_0_,
member0_.username as username3_0_
from
member member0_
where
member0_.username=?
MemberRepository Interface에서 @Query 부분을 주석처리하고 돌려도 같은 빌드 결과가 나오게 된다.
package study.datajpa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import study.datajpa.entity.Member;
import java.util.List;
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
List<Member> findTop3HelloBy();
// @Query(name = "Member.findByUsername")
// Member domain의 Member.findByUsername 해서 찾는다.
List<Member> findByUsername(@Param("username") String username);
}
@NamedQuery 실무에서 거의 사용하지 않는다. 스프링 데이터 JPA는 리포지토리 메소드에 쿼리를 지정하는 기능이 매우 강력하기 때문에 그걸 거의 많이 쓴다.
하지만 NamedQuery 장점이 뭐냐하면 JPQL쿼리에서 오류구문을 아래와 같이 냈을 때
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "username", "age"})
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.usernamㅁㄴㅇㄹㅁㄴㄹㅇe = :username"
)
build 실행시 아래와 같은 에러구문을 나타낸다.
exception is org.hibernate.HibernateException: Errors in named queries:
Member.findByUsername failed because of: org.hibernate.QueryException: could not resolve property: usernamㅁㄴㅇㄹㅁㄴㄹㅇe of: study.datajpa.entity.Member [select m from study.datajpa.entity.Member m where m.usernamㅁㄴㅇㄹㅁㄴㄹㅇe = :username]
<출처 김영한: 실전! 스프링 데이터 JPA >
실전! 스프링 데이터 JPA - 인프런 | 강의
스프링 데이터 JPA는 기존의 한계를 넘어 마치 마법처럼 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있습니다. 그리고 반복 개발해온 기본 CRUD 기능도 모두 제공합니다.
www.inflearn.com
'Spring > SpringDataJPA' 카테고리의 다른 글
@Query, 값, DTO 조회하기 & 파라미터 바인딩 (0) | 2022.04.17 |
---|---|
@Query, 리포지토리 메소드에 쿼리 정의하기 (0) | 2022.04.17 |
메소드 이름으로 쿼리 생성 (0) | 2022.04.15 |
공통 인터페이스 분석 (0) | 2022.04.15 |
공통 인터페이스 설정 & 적용 (0) | 2022.04.15 |