이 글은 '스프링 부트 핵심 가이드 - 스프링 부트를 활용한 애플리케이션 개발 실무' 책을 통해 학습한 내용을 정리한 글입니다.
08장. Spring Data JPA 활용
JPQL (JPA Query Language)
JPQL = JPA에서 사용할 수 있는 쿼리
문법은 SQL과 매우 비슷하지만 SQL에서는 칼럼의 이름을 사용하는 것과 달리 JPQL은 매핑된 엔티티의 이름과 필드의 이름을 사용한다.
SELECT p FROM Product p WHERE p.number = ?1;
쿼리 메서드
리포지토리는 JpaRepository를 상속받는 것만으로도 기본적인 CRUD 메서드를 제공하지만 별도의 메서드를 정의해서 사용하는 경우가 많다.
쿼리 메서드 생성
쿼리 메서드는 동작을 결정하는 주제(Subject)와 서술어(Predicate)로 구분한다. By로 서술어의 시작을 나타내어 구분자역할을 한다.
서술어 부분은 검색 및 정렬 조건을 지정하는 영역이며, 기본적으로 엔티티의 속성으로 정의할 수 있고, AND나 OR를 사용해 조건을 확장할 수도 있다.
// (리턴타입) + (주제 + 서술어)
List<Person> findByLastnamdAndEmail(String lastName, String email)
쿼리 메서드의 주제 키워드
- 조회하는 기능 : 리턴 타입 = Collection이나 Stream에 속한 하위 타입 설정
- find...By
- read...By
- get...By
- query...By
- search...By
- stream...By
- 특정 데이터가 존재하는지 확인
- exists...By : 리턴 타입 = boolean
- 조회 쿼리를 수행한 후 쿼리 결과로 나온 레코드의 개수 리턴
- count...By
- 삭제 기능 : 리턴 타입이 없거나 삭제한 횟수를 리턴
- delete...By
- remove...By
- 쿼리를 통해 조회된 결괏값의 개수를 제한
- 주제와 By 사이에 위치한다. 일반적으로 한 번의 동작으로 여러 건을 조회할 때 사용하며, 단 건으로 조회하기 위해서는 <number>를 생략하면 된다.
- ...First<number>...
- ...Top<number>...
쿼리 메서드의 조건자 키워드
- 값의 일치
- 생략되는 경우가 많다.
- Is, Equals
- 값의 불일치
- Is는 생략하고 Not 키워드만 사용할 수도 있다.
- (Is)Not
- 값이 null 인지 검사
- (Is)Null, (Is)NotNull
- boolean 타입으로 지정된 칼럼값을 확인
- (Is)True, (Is)False
- 여러 조건을 묶을 때 사용
- And, Or
- 비교 연산
- 숫자나 datetime 칼럼 대상
- 경곗값을 포함하려면 Than 뒤에 Equals를 추가해야 한다.
- (Is)GreaterThan, (Is)LessThan, (Is)Between
- 칼럼값에서 일부 일치 여부 확인
- SQL에서 % 키워드와 동일한 역할
- Like의 경우 메서드를 호출하면서 전달하는 값에 % 를 입력해야 한다.
- (Is)StartingWith(==StartsWith), (Is)EndingWith(==EndsWith), (Is)Containing(==Contains), (Is)Like
정렬과 페이징 처리
정렬
- OrderBy...Asc, OrderBy...Desc
- 정렬 구문은 And나 Or 키워드를 사용하지 않고 우선순위를 기준으로 차례대로 작성한다.
ex) List<Product> findByNameOrderByPriceAscStockDesc(String name);
먼저 Price를 기준으로 오름차순 정렬한 후 후순위로 Stock을 기준으로 내림차순 정렬을 수행한다. - 쿼리 메서드의 이름에 정렬 키워드를 삽입해서 정렬을 수행해도 좋지만 이름이 너무 길어지면 가독성이 떨어지기 때문에 매개변수를 활용해 정렬하는 방법도 있다.
- 이때는 메서드를 호출할 때 Sort.by(Order.asc("price")) 형식으로 변수를 전달하면 된다.
- 또한, Sort 부분을 하나의 메서드로 분리해서 쿼리 메서드를 호출하는 방법도 있다.
private Sort getSort() {
return Sort.by(
Order.asc("price"),
Order.desc("stock")
);
}
페이징 처리
페이징 = 데이터베이스의 레코드를 개수로 나눠 페이지를 구분하는 것
JPA에서는 페이징 처리를 위해 Page와 Pageable을 사용한다.
// 페이징 처리를 위한 쿼리 메서드
Page<Product> findByName(String name, Pageable pageable);
// 페이징 쿼리 메서드를 호출하는 방법
Page<Product> productPage = productRepository.findByName("펜", PageRequest.of(0, 2));
of 메서드
- of(int page, int size) : 페이지 번호(0부터 시작), 페이지당 데이터 개수를 매개변수로 받으며 데이터를 정렬하지 않는다.
- of(int page, int size, Sort) : 페이지 번호, 페이지당 데이터 개수, 정렬을 매개변수로 받으며 sort에 의해 정렬된다.
- of(int page, int size, Direction, String... properties) : 페이지 번호, 페이지당 데이터 개수, 정렬 방향, 속성(칼럼)을 매개변수로 받으며, Sort.by(direction, properties)에 의해 정렬된다.
Page 객체를 그대로 출력하면 해당 객체의 값을 보여주지 않고 몇 번째 페이지에 해당하는지만 확인할 수 있다.
각 페이지를 구성하는 세부적인 값을 보려면 아래 코드와 같이 작성해야 한다.
Page<Product> ProductPage = productRepository.findByName("펜", PageRequest.of(0, 2));
System.out.println(productPage.getContent());
QueryDSL
QueryDSL = 정적 타입을 이용해 SQL과 같은 쿼리를 생성할 수 있도록 지원하는 프레임워크
문자열이나 XML 파일을 통해 쿼리를 작성해는 대신 QueryDSL이 제공하는 Fluent API를 활용해 쿼리를 생성할 수 있다.
QueryDSL 장점
- IDE가 제공하는 코드 자동 완성 기능을 사용할 수 있다.
- 문법적으로 잘못된 쿼리를 허용하지 않기 땜누에 문법 오류를 발생시키지 않는다.
- 고정된 SQL 쿼리를 작성하지 않기 때문에 동적으로 쿼리를 생성할 수 있다.
- 코드로 작성하므로 가독성 및 생산성이 향상된다.
- 도메인 타입과 프로퍼티를 안전하게 참조할 수 있다.
JPA Auditing 적용
생성 주체, 생성 일자, 변경 주체, 변경 일자와 같은 필드들은 매번 엔티티를 생성하거나 변경할 때마다 값을 주입해야 하는데 이 값들을 자동으로 넣어주는 기능이 JPA Auditing 이다.
- @EnableJpaAuditing 어노테이션을 추가하여 사용할 수 있다.
- 그러나 main() 클래스에 추가하면 테스트하는 일부 상황에서 오류가 발생할 수 있다.
- 따라서 별도의 Configuration 클래스를 생성하여 사용하는 것을 권장한다.
- BaseEntity : 각 엔티티에 공통으로 들어가게 되는 컬럼을 하나의 클래스로 만든는 작업
// 공통으로 들어갈 칼럼 필드를 BaseEntity 클래스로 생성
@Getter
@Setter
@ToString
@MappedSuperclass
@EntityListeners(value = {AuditingEntityListener.class})
public abstract class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime modifiedAt;
}
- @MappedSuperclass : JPA의 엔티티 클래스가 상속받을 경우 자식 클래스에게 매핑 정보를 전달한다.
- @EntityListeners : 엔티티를 데이터베이스에 적용하기 전후로 콜백을 요청할 수 있게 한다.
- AuditingEntityListener : 엔티티의 Auditing 정보를 주입하는 JPA 엔티티 리스너 틀래스
- @CreatedDate : 데이터 생성 날짜를 자동으로 주입한다.
- @LastModifiedDate : 데이터 수정 날짜를 자동으로 주입한다.
+ @CreatedBy, @ModifiedBy : 누가 엔티티를 생성했고 수정했는지 자동으로 값을 주입하는 기능, 이 기능을 사용하려면 AuditorAware를 스프링 빈으로 등록해야 한다.
'북 스터디 > 스프링 부트 핵심 가이드' 카테고리의 다른 글
[스프링 부트] 10장. 유효성 검사와 예외 처리 (0) | 2023.06.25 |
---|---|
[스프링 부트] 09장. 연관관계 매핑 (0) | 2023.06.18 |
[스프링 부트] 06장. 데이터베이스 연동 (0) | 2023.06.04 |
[스프링 부트] 04장 ~ 05장 (0) | 2023.05.28 |
[스프링 부트] 02장. 개발에 앞서 알면 좋은 기초 지식 (0) | 2023.05.21 |