[ZB_BOOK STUDY] 스프링 부트 핵심 가이드 (8-1)

Dreamer·2024년 4월 14일
0
post-thumbnail

📖 스프링 부트 핵심 가이드

: 스프링 부트를 활용한 애플리케이션 개발 실무


📝 목차

8장. Spring Data JPA 활용

8-1. 프로젝트 생성
8-2. JPQL
8-3. 쿼리 메서드 살펴보기
- 쿼리 메서드의 생성
- 쿼리 메서드의 주제 키워드
- 쿼리 메서드의 조건자 키워드


8장. Spring Data JPA 활용

  • Spring Data JPA에서 제공하는 기능들을 알아보고 활용해보자

8-1. 프로젝트 생성

8-2. JPQL (JPA Query Language)

: JPA에서 사용할 수 있는 쿼리
JPQL의 문법은 SQL과 매우 비슷하며, SQL을 기반으로 한 언어다.

JPQL과 SQL과의 차이점
: JPQL은 데이터베이스의 테이블이 아니라, JPA에서 매핑한 엔티티 객체를 대상으로 쿼리를 수행한다.
➙ SQL에서 사용하는 테이블 이름, 칼럼 이름 대신 JPQL에서는 매핑된 엔티티 클래스의 이름과 그 속성(필드) 이름을 사용하여 쿼리를 작성!

JPQL쿼리의 기본 구조

8-3. 쿼리 메서드 살펴보기

: 리포지토리(Repository)는 JpaRepository를 상속 ➙ 다양한 CRUD 메서드를 제공
기본 메서드들은 식별자 기반으로 생성 ➙ 결국 별도의 메서드를 정의해 사용
이때, 간단한 쿼리문을 작성하기 위해 사용되는 것 = 쿼리 메서드

- 쿼리 메서드의 생생

쿼리 메서드 = 동작을 결정하는 주제 (Subject) + 서술어 (Predicate)

[Subject]

  • 'find...By' 'exists...By'와 같은 키워드로 쿼리의 주제를 정한다.
  • 'By' ➙ 서술어의 시작을 나타내는 구분자 역할

[Predicate]

  • 검색 및 정렬 조건을 지정하는 영역
  • 기본적으로 엔티티의 속성으로 정의할 수 있고, AND, OR을 사용해 확장 가능
✅ 리포지토리의 쿼리 메서드 생성 예시
// (리턴 타입) + {주제 + 서술어(속성)} 구조의 메서드
List<Person> findByLastnameAndEmail (String lastName, String email);

서술어에 들어가는 엔티티의 속성 식(Expression)은 ➙ LastnameAndEmail
위의 예시와 같이 엔티티에서 관리하고 있는 속성(필드)만 참조할 수 있다.

- 쿼리 메서드의 주제 키워드 ➙ 주요 키워드

'...'으로 표시한 영역에는 도메인(엔티티)을 표현 할 수 있다.
리포지토리에서 이미 도메인을 설정한 후 메서드를 사용 ➙ 생략 가능

✅ 조회하는 기능을 수행하는 키워드
➡️ 리턴 타입 : Collection이나 Stream에 속한 하위 타입 설정

  • 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);

✅ 특정 데이터가 존재하는지 확인하는 키워드
➡️ 리턴 타입 : boolean 타입 사용

  • exists...By
//exists...By
boolean existsByNumber(long number);

✅ 조회 쿼리를 수행 ➡️ 쿼리 결과로 나온 레코드의 개수를 리턴

  • count...By
//count...By
long countByName(String name);

✅ 삭제 쿼리 수행 ➡️ 리턴 타입이 없거나, 삭제한 횟수를 리턴

  • delete...By
  • remove...By
//delete...By, remove...By
void deleteByNumber(long number);
long removeByName(String name);

✅ 쿼리를 통해 조회된 결괏값의 개수를 제한하는 키워드
두 키워드는 동일한 동작을 수행

  • ...First...
  • ...Top...

주제와 By 사이에 위치
한번의 동작으로 여러 건을 조회할 때 사용되며,
단 건으로 조회하기 위해서는 <number> 를 생략하면 된다.

//...First<number>..., ...Top<number>...
List<Product> findFirst5ByName(String name);
List<Product> findTop10ByName(String name);

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

: JPQL의 서술어 부분에서 사용할 수 있는 조건자 키워드

✅ 값의 일치를 조건으로 사용하는 조건자 키워드
: 생략되는 경우가 많고, Equals와 동일한 기능을 수행

  • Is
// findByNumber 메서드와 동일하게 동작
Product findByNumberIs(Long number);
Product findAllByNumberIs(Long number);

✅ 값의 불일치를 조건으로 사용하는 조건자 키워드
: Is는 생략하고 Not 키워드만 사용할 수도 있다.

  • (Is) Not
//(is)Not
Product findByNumberIsNot(Long number);
Product findByNumberNot(Long number);

✅ 값이 null인지 검사하는 조건자 키워드

  • (Is)Null
  • (Is)NotNull
//(Is)Null, (Is)NotNull
List<Product> findByUpdatedAtNull();
List<Product> findByUpdatedAtIsNull();
List<Product> findByUpdatedAtNotNull();
List<Product> findByUpdatedAtIsNotNull();

✅ boolean 타입으로 지정된 컬럼값을 확인하는 키워드
: 엔티티에 boolean 타입을 사용하는 칼럼이 없으면 에러가 발생

  • (Is)True
  • (Is)False
//(Is)True, (Is)False
Product findByisActiveTrue();
Product findByisActiveIsTrue();
Product findByisActiveFalse();
Product findByisActiveIsFalse();

✅ 여러 조건을 묶을 때 사용

  • And
  • Or
//And, Or
Product findByNumberAndName(Long number, String name);
Product findByNumberOrName(Long number, String name);

✅ 비교연산에 사용할 수 있는 조건자 키워드 ➡️ 숫자, datetime 칼럼만!
: 경계값을 포함하려면 Equal 키워드 추가

  • (Is)GreaterThan - 초과
  • (Is)LessThan - 미만
  • (Is)Between
 // (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);

✅ 칼럼값에서 일부 일치 여부를 확인하는 조건자 키워드

  • (Is)StartingWith(==StartsWith)
  • (Is)EndingWith(==EndsWith)
  • (Is)Containing(==Contains)
  • (Is)Like

⬇️

SQL 쿼리문에서 값의 일부를 포함하는 값을 추출할 때 사용하는 % 키워드와 동일한 역할을 하는 키워드
여기서 별도로 고려해야하는 Like키워드

  • Like키워드는 코드 수준에서 메서드를 호출하면서 전달하는 값에 %를 명시적으로 입력해야 한다.

    // (Is)StartingWith(==StartsWith),
    // (Is)EndingWith(==EndsWith)
    // (Is)Containing(==Contains)
    // (Is)Like
    
    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);
profile
Moving forward based on records

0개의 댓글