슴새 2024. 1. 6. 17:23
반응형

JPQL

JPQL은 jpa query language의 줄임말로 sql과 거의 비슷하게 생겼으나, 테이블 대신 엔티티 이름이 들어간다. 

(그야 jpa는 엔티티 이름을 기반으로 테이블을 생성하니... 개인적으론 거의 sql과 똑같이 느껴진다.)

SELECT p FROM Product p WHERE p.number=1;

이런식으로 되어있는게 JPQL이다.

 

쿼리 메서드 살펴보기

이런 JPQL을 어떻게 작성할 수 있느냐...하면,

일단 리포지토리는 JpaRepository를 상속받는 것만으로도 다양한 CRUD 메서드를 제공한다. 

findById 같은...

그리고 이 기본 메서드를 호출하면 jpql이 알아서 생성돼서 쿼리문을 수행한다. 

public interface ProductRepository extends JpaRepository<Product, Long> {

}

 

그리고 이 리포지토리에서 규칙에 맞게 메소드를 작성하면, 더 다양한 쿼리문을 생성할 수 있다.

인터페이스라고 impl 을 구현할 필요는 전혀 없다.

이렇게 규칙에 맞게 작성한걸 쿼리 메서드라고 한다. 

 

쿼리메서드는 크게

  • find...By
  • read...By
  • get...By
  • query...By
  • search...By
  • stream...By

가 있다.

 

find...By

Optional<Product> findByNumber(Long number);
List<Product> findAllByName(String name);
Product queryByNumber(Long number);

보이는 그대로의 성능

 

exist...By

boolean existsByNumber(Long number);

특정 데이터가 있는지 확인하며, 리턴형은 Boolean

 

count...By

long countByName(String name);

조회쿼리를 수행한 후 그 갯수를 반환 

 

delete .. by, remove ...by

void deleteByNumber(Long number);
long removeByName(String name);

삭제 쿼리를 수행한다. 리턴타입이 없거나 삭제한 횟수를 리턴.

 

First<number>... , Top<number>

List<Product> findFirst5ByName(String name);
List<Product> findTop10ByName(String name);

결과값의 개수를 제한한다. 오라클 sql의 where rownum<5 같은 구문과 비슷한듯

 

이런 쿼리메서드는 

findByLastnameAndEmail 같은 식으로 And 나 or을 붙여 조건을 확장할 수도 있다.

 

쿼리 메서드의 조건자 키워드

Is,Equals (생략가능)

   // findByNumber 메소드와 동일하게 동작
    Product findByNumberIs(Long number);
    Product findByNumberEquals(Long number);

생략되는 경우가 많다.

 

(Is)Not

Product findByNumberIsNot(Long number);
Product findByNumberNot(Long number);

값의 불일치를 조건으로 사용하는 키워드.

Is는 생략하고 Not만 써도 된다.

 

(Is)Null, (Is)NotNull

List<Product> findByUpdatedAtNull();
List<Product> findByUpdatedAtIsNull();
List<Product> findByUpdatedAtNotNull();
List<Product> findByUpdatedAtIsNotNull();

값이 null인지 검사하는 키워드

 

(Is)GreaterThan, (Is)LessThan, (Is)Between

List<Product> findByPriceIsGreaterThan(Long price);
List<Product> findByPriceGreaterThan(Long price);
List<Product> findByPriceGreaterThanEqual(Long price);
List<Product> findByPriceIsLessThan(Long price);
List<Product> findByPriceLessThan(Long price);
List<Product> findByPriceLessThanEqual(Long price);
List<Product> findByPriceIsBetween(Long lowPrice, Long highPrice);
List<Product> findByPriceBetween(Long lowPrice, Long highPrice);

숫자나 datetime 칼럼을 대상으로 비교 연산을 할 수 있는 키워드.

초과/미만으로 비교하고, 경곗값을 포함하려면 Equal 키워드를 추가하면 된다.

 

(Is)Like, (Is)Containing, (Is)StartingWith, (Is)EndingWith 

List<Product> findByNameLike(String name);
List<Product> findByNameIsLike(String name);

List<Product> findByNameContains(String name);
List<Product> findByNameContaining(String name);
List<Product> findByNameIsContaining(String name);

List<Product> findByNameStartsWith(String name);
List<Product> findByNameStartingWith(String name);
List<Product> findByNameIsStartingWith(String name);

List<Product> findByNameEndsWith(String name);
List<Product> findByNameEndingWith(String name);
List<Product> findByNameIsEndingWith(String name);

일부 일치를 확인한다.

StartingWith은 like '%키워드'

Containing은 like '%키워드%'

EndingWith는 like '키워드%'

Like는 아예 인자로 '%키워드%' 이렇게 %를 붙여서 해야한다.  %없이 쓰고싶을땐 그냥 호출하면 될듯

 

반응형