본문 바로가기
개발 관련 공부/스프링부트 핵심 가이드

08 Spring Data JPA 활용

by 슴새 2024. 1. 6.
반응형

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

 

반응형

댓글