Core concepts

2024. 10. 19. 17:40Spring Boot/Spring Data JPA

Repository 인터페이스

  • 중심 인터페이스: Spring Data 리포지토리 추상화의 중심 인터페이스는 Repository입니다. 이 인터페이스는 관리할 도메인 클래스와 도메인 클래스의 identifier 타입을 제네릭 타입 파라미터로 받습니다. 기본적으로 이 인터페이스는 마커 인터페이스로 사용되며, 작업할 타입을 캡처하고 이를 확장하는 인터페이스를 발견하는 데 도움을 줍니다.
  • 도메인 객체: Spring Data는 도메인 타입을 엔티티로 간주하며, 보다 구체적으로 집합체(aggregate)로 설명합니다. 따라서 문서 전반에 걸쳐 "엔티티"라는 용어가 사용되며, 이는 "도메인 타입"이나 "집합체"와 상호 교환할 수 있습니다.
  • 도메인 주도 설계(DDD): 도메인 객체는 DDD의 관점에서 정의됩니다. 도메인 객체는 identifier를 가지고 있으며, 특정 패턴으로 데이터에 접근할 때 이 identifier를 참조해야 합니다. identifier를 참조하는 것은 리포지토리 및 쿼리 메서드를 다룰 때 더 의미 있게 됩니다.

CrudRepository 인터페이스

CrudRepository는 관리되는 엔티티 클래스에 대한 고급 CRUD 기능을 제공합니다.

public interface CrudRepository<T, ID> extends Repository<T, ID> {

  <S extends T> S save(S entity); // (1)

  Optional<T> findById(ID primaryKey); // (2)

  Iterable<T> findAll(); // (3)

  long count(); // (4)

  void delete(T entity); // (5)

  boolean existsById(ID primaryKey); // (6)

  // ... 더 많은 기능 생략됨.
}

 

  1. save(S entity): 주어진 엔티티를 저장합니다. (새로운 엔티티는 삽입되고, 기존 엔티티는 업데이트됨)
  2. findById(ID primaryKey): 주어진 ID로 식별되는 엔티티를 리턴합니다.
  3. findAll(): 모든 엔티티를 리턴합니다.
  4. count(): 현재 저장된 엔티티의 수를 리턴합니다.
  5. delete(T entity): 주어진 엔티티를 삭제합니다.
  6. existsById(ID primaryKey): 주어진 ID를 가진 엔티티가 존재하는지 여부를 나타냅니다.

CRUD 메서드

  • CrudRepository 인터페이스에 선언된 메서드는 일반적으로 CRUD 메서드라고 불립니다.

ListCrudRepository

  • ListCrudRepositoryCrudRepository와 동일한 메서드를 제공하지만, 리턴 타입이 List인 반면 CrudRepositoryIterable을 리합니다.

주의 사항

  • 리포지토리 인터페이스는 findById(ID identifier)와 같은 몇 가지 예약된 메서드를 포함합니다. 이 메서드는 도메인 타입의 identifier 속성을 목표로 하며, 속성 이름과 관계없이 동작합니다.
  • 만약 식별자를 참조하는 속성이 Id라는 이름이 아닐 경우, @Query 애노테이션을 사용하여 커스텀 쿼리를 제공할 수 있습니다. 그러나 이렇게 하면 혼란스러울 수 있으며, ID 타입과 Id 속성의 타입이 다를 경우에는 더 많은 제약을 받을 수 있으므로 이러한 경로를 피하는 것이 좋습니다.

JpaRepository 및 MongoRepository

  • JpaRepository 또는 MongoRepository와 같은 특정 영속성 기술에 대한 추상화도 제공됩니다. 이러한 인터페이스는 CrudRepository를 확장하며, 기본적인 CRUD 기능 외에 특정 영속 기술의 기능을 추가로 노출합니다.

PagingAndSortingRepository 인터페이스

  • PagingAndSortingRepositoryListPagingAndSortingRepository는 엔티티에 대한 페이지 접근을 쉽게 하기 위해 추가적인 메서드를 제공합니다.
public interface PagingAndSortingRepository<T, ID> {

  Iterable<T> findAll(Sort sort);

  Page<T> findAll(Pageable pageable);
}
  • findAll(Sort sort): 주어진 정렬 기준에 따라 모든 엔티티를 리턴합니다.
  • findAll(Pageable pageable): 주어진 페이지 요청에 따라 엔티티를 페이지 단위로 리합니다.

주의 사항

  • 확장 인터페이스는 실제 저장소 모듈에 의해 지원됩니다. 따라서 이 문서에서 설명하는 일반적인 체계와는 별개로, 사용하려는 인터페이스가 사용 중인 저장소 모듈에서 지원되는지 확인해야 합니다.

예제: 페이지 접근

사용자(User) 엔티티에 대해 페이지 크기가 20인 두 번째 페이지에 접근하려면 다음과 같이 할 수 있습니다:

PagingAndSortingRepository<User, Long> repository = // ... bean에 접근
Page<User> users = repository.findAll(PageRequest.of(1, 20));

ListPagingAndSortingRepository는 동일한 메서드를 제공하지만, 리턴 타입이 List인 반면 PagingAndSortingRepositoryIterable을 리합니다.

쿼리 메서드

  • 쿼리 메서드에 대한 파생 쿼리도 가능합니다. 다음은 파생된 카운트 쿼리의 인터페이스 정의입니다.

파생된 카운트 쿼리

interface UserRepository extends CrudRepository<User, Long> {

  long countByLastname(String lastname);
}

파생된 삭제 쿼리

interface UserRepository extends CrudRepository<User, Long> {

  long deleteByLastname(String lastname);

  List<User> removeByLastname(String lastname);
}
  • countByLastname(String lastname): 주어진 성(lastname)을 가진 사용자 수를 리턴합니다.
  • deleteByLastname(String lastname): 주어진 성을 가진 사용자를 삭제하고 삭제된 사용자 수를 리턴합니다.
  • removeByLastname(String lastname): 주어진 성을 가진 사용자를 삭제하고 삭제된 사용자 목록을 리턴합니다.

 

Spring Data 리포지토리의 기본 구조와 사용법을 이해하는 것은 애플리케이션 개발 시 데이터에 접근하고 조작하는 데 큰 도움이 됩니다. CrudRepository, PagingAndSortingRepository, 그리고 이들 인터페이스의 파생된 메서드들에 대한 이해는 데이터 처리의 유연성과 효율성을 높여줄 것입니다. 이러한 기능들은 데이터베이스와의 상호작용을 단순화하고, 도메인 객체에 대한 CRUD 작업을 손쉽게 수행할 수 있게 도와줍니다.

'Spring Boot > Spring Data JPA' 카테고리의 다른 글

Configuration  (3) 2024.10.19
Defining Repository Interfaces  (0) 2024.10.19
Getting Started  (0) 2024.10.19
Query Hint  (0) 2023.06.06
Database Index  (0) 2023.06.04