Hello

Spring Data Jpa 쿼리 메소드, 네이밍 규칙, 네이티브 쿼리

by 볼빵빵오춘기

Spring Data Jpa 쿼리 메소드

Spring Data JPA의 쿼리 메소드는 리포지토리 인터페이스에서 메소드 이름을 분석하여 자동으로 JPQL (Java Persistence Query Language) 쿼리를 생성하는 기능을 제공한다.
⇒ 개발자는 복잡한 SQL을 직접 작성할 필요 없이, 메소드 이름만으로도 다양한 쿼리를 쉽게 구현할 수 있다.

 

네이밍 규칙

 

  • 메소드 이름 시작
    findBy, readBy, queryBy, getBy, countBy, deleteBy (※ 메소드 이름을 보면 어떤 기능을 하는 메소드인지 짐작할 수 있다.)
기능 메소드 이름 시작
조회 findBy, readBy, queryBy, getBy,...
count countBy (반환타입 long),....
exists existsBy (반환타입 boolean),...
삭제 deleteBy, removeBy,...
distinct findDistinct,....

 

  • 속성 이름
    엔티티 클래스의 필드 이름을 사용
  • 연산자(= 키워드)
    And, Or, Between, LessThan, GreaterThan, Like, Not, In, OrderBy, 등
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)

 

네이밍 규칙 사용방법

가정: 엔티티 클래스에 name 필드가 있으며, 데이터베이스에서 name이 'jinny'인 컬럼을 조회하고자 한다.

 

메소드 선택

데이터를 찾기 위해 사용할 메소드를 선택한다. 

ex) findBy

 

엔티티 연결 

findBy 뒤에 엔티티 필드를 연결한다. 

이때 연결할 때는 카멜 표기법을 사용하여 연결 단어의 첫 글자를 대문자로 작성한다.
ex) findByName

 

파라미터 추가

메소드에 조회할 값을 파라미터로 넣어준다.(넣어줄 필요가 없다면 이 부분 생략)

findByName(String name)

 

⇒ 이 메소드를 사용하는 곳에  findByName('jinny')를 써주면 조회가 된다.

 

 

연산자 추가

위에 가정 부분에 엔티티 클래스에 name 필드가 있으며, 데이터베이스에서 name이 'jinny'이고 id가 3인 컬럼을 조회하고자 한다라고 한다면 연산자를 이용해 추가할 수 있다.

ex) findByIdAndName(3,String name)

 

예시 코드

엔티티 클래스

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    private int age;
}

 

리포지토리 인터페이스에서 쿼리 메소드를 정의

public interface UserRepository extends JpaRepository<User, Long> {
    // 기본 제공 CRUD 메소드 외에 커스텀 쿼리 메소드

    // 단일 속성 기반 쿼리
    List<User> findByName(String name);

    // 여러 속성 기반 쿼리
    List<User> findByNameAndAge(String name, int age);

    // 연산자 사용 쿼리
    List<User> findByAgeLessThan(int age);

    List<User> findByAgeGreaterThan(int age);

    List<User> findByNameContaining(String namePart);

    // 정렬 사용 쿼리
    List<User> findByNameOrderByAgeAsc(String name);

    // 복합 조건 쿼리
    List<User> findByAgeBetween(int startAge, int endAge);

}

 


 

 

JPA를 사용하고있지만 네이티브 쿼리를 사용해야 할 경우가 생긴다. 

이럴 땐 어떻게 해야할까?

 

네이티브 쿼리 사용방법

@Entity
@Table(name = "DA_CommunityBbs")
public class CommunityEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id; // pk

    @Column(nullable = false,length = 100)
    private String title; // 제목

    @Lob
    private String content; // 내용
    
    // ..생략
}
@Repository
public interface CommnunityRepository extends JpaRepository<CommunityEntity, Integer> {

    @Modifying
    @Query(value=" update CommunityEntity c set c.count = c.count + 1 where c.id = :id ")
    void updateConunt(@Param("id") int id);

}

 

@Query 어노테이션 추가

리포지토리 인터페이스 메소드에 @Query 어노테이션을 추가하여 쿼리를 정의한다.

nativeQuery = true를 설정하여 네이티브 쿼리를 사용할 수 있다.(설정하지 않아도 기본 nativeQuery가 true로 되어있다.)

 

파라미터 바인딩

쿼리에서 사용되는 매개변수를 @Param 어노테이션으로 메소드 파라미터와 연결한다.

※ 쿼리 작성 된 부분에 :이름 작성해주고 메소드에는 @Param(이름)을 통해 연결

JPA 네이티브 쿼리 파라미터 바인딩

위에 보면 :id와 @Param("id") 연결을 통해 파라미터 int id가 네이티브쿼리에 저 위치에 들어간다고 알려주는 것!

:이름 과 @Param("이름") 이 동일해야 연결된다.

 

테이블명 별칭 사용

테이블 이름 뒤에 별칭을 붙여서 사용해야한다.

JPA 네이티브 쿼리 테이블명 별칭 사용

※ 테이블명이 들어가는 부분에는 실질적으로 DB와 매핑이되는 엔티티클래스명을 적어주면된다.

@Entity
@Table(name = "DA_CommunityBbs")
public class CommunityEntity {
// .. 생략

 

클래스명을 CommunityEnity 하였지만 실제 DB에 table명은 DA_CommunityBbs 로 하였었다. 

DB table

 


 

참고링크

https://wisdom-cs.tistory.com/66

https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html

 

 

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기