8. Working with Spring Data Repositories
https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#repositories.core-concepts
스프링 데이터 리포지토르 추상화의 목표는 다양한 영속성 저장을 위한 데이터 접근 레이어의 구현에 필요한 보일러 플레이트 코드의 상당부분을 줄이는 것이다.
(중요)
스프링 데이터 리포지토리 문서와 당신의 모듈
이 챕터는 스프링 데이터 리포지토리의 핵심 개념과 인터페이스를 설명한다. 이 챕터의 정보는 스프링 데이터 커먼 모듈에서 왔다. 이 챕터는 Jakarta Persistence API(JPA) 모듈을 위한 코드 샘플과 설정을 사용한다. "리포지토리 쿼리 키워드"는 일반적인 리포지토리 추상화에 의해 지원되는 쿼리 메소드 키워드를 다룬다. 당신의 모듈의 특정 기능에 대한 상세한 정보는, 이 문서의 그 모듈을 다루는 챕터에서 확인해봐라.
8.1. 핵심 개념
스프링 데이터 리포지토리 추상화에서 중심 인터페이스는 Repository다. 도메인 클래스와 도메인 클래스의 ID 타입을 타입 인수로 관리 해야 합니다. 이 인터페이스는 이 인터페이스를 상속한 인터페이스를 발견하기위해 당신을 도와주고 함께일할 타입을 찾는 마커 인터페이스로서 주요하게 동작한다. CurdRepository 와 ListCrudRepository 인터페이스는 관리되는 엔터티 클래스를 위한 정교한 CRUD 기능을 제공한다.
예제3. CrudRepository Interface
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity); // 1
Option<T> findById(ID primaryKey); // 2
Iterable<T> findAll(); // 3
long count(); // 4
void delete(T entity); // 5
boolean existsById(ID primaryKey); // 6
// ... more functionality omitted.
}
1. 주어진 엔터티를 저장한다.
2. 주어진 ID로 식별되는 엔터티를 리턴한다.
3. 모든 엔터티를 리턴한다.
4. 엔터티의 갯수를 리턴한다.
5. 주어진 엔터티를 삭제한다.
6. 주어진 ID의 엔터티가 존재하는지를 확인한다.
ListCrudRepository는 동일한 메소드들을 제공하지만, CurdRepository 메소드들이 Iterable을 리턴하는것과 다르게 List를 리턴한다.
(알림)
우리는 또한 JpaRepository 나 MongoRepository같은 영속성 기술별 추상화를 제공한다. 이 인터페이스들은 CrudRepository를 확장하고, CrudRepository같은 일반적인 영속성 기술에 구애받지 않는 인터페이스 외에도 기본 영속성 기술의 기능을 제공한다.
CrudRepository에 더해, 엔터티에 쉬운 페이징 가능한 접근을 하는 추가적인 메소드를 더한 PagingAndSortingRepository 추상화가 있다.
예제4. PagingAndSortingRepository interface
public interface PagingAndSortingRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pagealbe);
}
20개의 페이지 사이즈로 User의 두번째 장에 접근하려면, 이렇게 하면 된다:
PagingAndSortingRepository<User, Long> repository = // ... get accress to a bean
Page<User> users = respository.findAll(PageRequest.of(1, 20));
쿼리 메소드 외에도, 셈과 삭제를 위한 쿼리 둘다 쿼리 유도 (query derivation)이 가능하다. 다음은 셈을 하는 쿼리를 유도해낸 인터페이스 정의를 보여준다:
예제 5. Derived Count Query (파생된 셈 쿼리)
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);
}