본문 바로가기
JPA

Data JPA 쿼리메소드

by 혀눅짱 2023. 10. 10.

쿼리 메소드 기능 3가지

  • 메소드이름으로 쿼리생성
  • 메소드이름으로 JPA NamedQuery 호출 
  • @Query 어노테이션을 활용하여 리파지토리 인터페이스에 쿼리 직접 정의

 

예제

public List<Member> findByName(String name){
    return em.createQuery("select m from Member m where m.name=:name", Member.class)
            .setParameter("name",name).getResultList();
}

해당 소스는 순수JPA 리포지토리를 이용한 JPQL임 .

 

쿼리 메소드는 Repository 인터페이스에 간단한 네이밍 룰을 이용하여 메소드를 작성하면 원하는 쿼리를 실행할 수 있음.

 

Data JPA의 메소드이름 쿼리생성방식으로 변경하면 쉽게 소스를 줄일수 있음.

public interface MemberDataJpaRepository extends JpaRepository<Member, Long> {

    List<Member> findByName(String name);

    
}


먼저 인터페이스에서 JPA레포지토리를 상속함(엔티티명, 엔티티식별자 타입);

메소드명에서 by는 where 절을 뜻함. 그밖에 각종 메소드명명 규칙은 다음 표 와 링크 참고

 

Distinct findDistinctByLastnameAndFirstname select distinct …​ where x.lastname = ?1 and x.firstname = ?2
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is, Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull, Null findByAge(Is)Null … where x.age is null
IsNotNull, NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection<Age> ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection<Age> ages) … where x.age not in ?1
True findByActiveTrue() … where x.active = true
False findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstname) = UPPER(?1)

 

다음은 @NamedQuery 사용법

 

@NamedQuery 어노테이션으로 쿼리에 이름을 부여 및 정의하여 호출, 사용한다. 엔티티의 쿼리를 선언해야해서 그닥 가독성이 좋은 방법은 아닌것 같지만 일단 예제는 만들어보았다.

 

@NamedQuery(
        name="Member.findByName",
        query="select m from Member m where m.username = :username"
)
public class Member extends BaseEntity{

 

public interface MemberDataJpaRepository extends JpaRepository<Member, Long> {

    @Query(name = "Member.findByName") // 선언을 하지 않아도 spring data jpa가 알아서 관례상 찾아 넣어주긴 함
    List<Member> findByName(@Param("username") String username);

}

엔티티에 쿼리를 정의하고 리포지토리에서 @Query로 호출하면 된다고한다.

복습하면서 기록하는거긴한데 확실히 그전에 공부할때 대강 보고 넘어가서 기억이 잘 안났다. 알아만 두도록해야겠다.

 

마지막으론 @Query어노테이션에 직접 쿼리를 정의하는방식이다.

public interface MemberDataJpaRepository extends JpaRepository<Member, Long> {

    @Query("select m from Member m where m.name= :name") 
    List<Member> findByName(@Param("name") String username);


}

제일 직관적이고 이방법 역시 컴파일시점에 에러를 잡아줘서 굉장히 효율적인 것 같다. 일단 첫번째 메소드이름으로 정의하면 

파라미터와 조건이 많아질수록 메소드의 이름이 명명규칙에 의해 길어지기때문에 가독성이 매우 떨어지게된다. 

 

Data JPA를 잘 활용하면 순수 jpa  jpql 보다 훨씬 간편하게 구현 할 수 있다.

 

'JPA' 카테고리의 다른 글

Data JPA collection 파라미터 바인딩  (0) 2023.10.11
@Query 값, DTO로 반환받기  (0) 2023.10.11
변경감지  (0) 2023.10.06
Join vs Fetch Join  (1) 2023.10.04
즉시로딩 과 지연로딩 그리고 N+1  (0) 2023.09.20