2024.02.03 - [웹/Spring] - Spring Data JPA - 핵심 개념
Spring Data JPA - 핵심 개념
2024.02.03 - [끄적이기] - JPA에 대해서 JPA에 대해서 JPA? 자바 퍼시스턴스(Java Persistence, 이전 이름: 자바 퍼시스턴스 API/Java Persistence API) 또는 자바 지속성 API(Java Persistence API, JPA)는 자바 플랫폼 SE와
kwaksh2319.tistory.com
저장소 인터페이스를 정의하려면 먼저 도메인 클래스별 저장소 인터페이스를 정의해야 합니다. 인터페이스는 Repository를 확장하고 도메인 클래스 및 ID 유형에 타입이 지정되어야 합니다. 해당 도메인 유형에 대한 CRUD 메소드를 노출하려면 Repository 대신 CrudRepository 또는 그 변형 중 하나를 확장할 수 있습니다.
저장소 인터페이스 정의를 세밀하게 조정하는 방법에는 몇 가지 변형이 있습니다.
전형적인 접근 방식은 CrudRepository를 확장하는 것이며, 이는 CRUD 기능을 위한 메소드를 제공합니다. CRUD는 생성(Create), 읽기(Read), 업데이트(Update), 삭제(Delete)를 의미합니다. 버전 3.0에서는 ListCrudRepository도 도입했는데, 이는 CrudRepository와 매우 유사하지만 다수의 엔티티를 반환하는 메소드의 경우 Iterable 대신 List를 반환하여 사용하기 더 쉬울 수 있습니다.
반응형 저장소를 사용하는 경우 사용하는 반응형 프레임워크에 따라 ReactiveCrudRepository 또는 RxJava3CrudRepository를 선택할 수 있습니다.
Kotlin을 사용하는 경우 코틀린의 코루틴을 활용하는 CoroutineCrudRepository를 선택할 수 있습니다.
추가로, Sort 추상화를 지정할 수 있는 메소드가 필요한 경우 PagingAndSortingRepository, ReactiveSortingRepository, RxJava3SortingRepository 또는 CoroutineSortingRepository를 확장할 수 있습니다. 첫 번째 경우 Pageable 추상화를 지정할 수 있습니다. 다양한 정렬 저장소는 Spring Data 버전 3.0 이전처럼 각각의 CRUD 저장소를 확장하지 않습니다. 따라서 두 기능 모두를 원하는 경우 두 인터페이스를 모두 확장해야 합니다.
Spring Data 인터페이스를 확장하고 싶지 않은 경우, @RepositoryDefinition으로 저장소 인터페이스를 주석 처리할 수도 있습니다. CRUD 저장소 인터페이스 중 하나를 확장하면 엔티티를 조작하는 메소드의 완전한 세트가 노출됩니다. 노출되는 메소드를 선택적으로 결정하고 싶다면, 원하는 메소드를 CRUD 저장소에서 도메인 저장소로 복사하세요. 이렇게 할 때 메소드의 반환 유형을 변경할 수 있습니다. 가능한 경우 Spring Data는 반환 유형을 존중합니다. 예를 들어, 다수의 엔티티를 반환하는 메소드의 경우 Iterable<T>, List<T>, Collection<T> 또는 VAVR 리스트를 선택할 수 있습니다.
애플리케이션의 많은 저장소가 같은 메소드 세트를 가져야 한다면, 상속받을 자체 기본 인터페이스를 정의할 수 있습니다. 이러한 인터페이스는 @NoRepositoryBean으로 주석 처리되어야 합니다. 이는 Spring Data가 직접 인스턴스를 생성하려고 시도하고 실패하는 것을 방지하기 위함입니다. 왜냐하면 여전히 일반 유형 변수를 포함하고 있어 해당 저장소의 엔티티를 결정할 수 없기 때문입니다.
다음 예시는 CRUD 메소드(이 경우 findById와 save)를 선택적으로 보여줍니다.
@NoRepositoryBean
interface MyBaseRepository<T, ID> extends Repository<T, ID> {
Optional<T> findById(ID id);
<S extends T> S save(S entity);
}
interface UserRepository extends MyBaseRepository<User, Long> {
User findByEmailAddress(EmailAddress emailAddress);
}
이전 예시에서, 모든 도메인 저장소에 대한 공통 기본 인터페이스를 정의하고 findById(...)와 save(...) 메소드를 노출시켰습니다. 이 메소드들은 CrudRepository에 있는 메소드 시그니처와 일치하기 때문에, 선택한 저장소의 Spring Data 제공 기본 저장소 구현체(예를 들어, JPA를 사용하는 경우 SimpleJpaRepository 구현체)로 라우팅됩니다. 따라서 UserRepository는 이제 사용자를 저장하고, ID로 개별 사용자를 찾고, 이메일 주소로 사용자를 찾기 위한 쿼리를 트리거할 수 있습니다.
애플리케이션에서 단일 Spring Data 모듈을 사용하는 것은 모든 저장소 인터페이스가 정의된 범위 내에서 해당 Spring Data 모듈에 바인딩되기 때문에 일이 간단해집니다. 그러나 때로는 둘 이상의 Spring Data 모듈을 사용해야 하는 상황이 발생합니다. 이런 경우에는 저장소 정의가 영속성 기술 사이를 구별해야 합니다. 클래스 경로상에 여러 저장소 팩토리가 감지되면, Spring Data는 엄격한 저장소 구성 모드로 전환됩니다. 엄격한 구성은 저장소 또는 도메인 클래스에 대한 세부 정보를 사용하여 저장소 정의에 대한 Spring Data 모듈 바인딩을 결정합니다:
- 저장소 정의가 모듈 특정 저장소를 확장하는 경우, 해당 Spring Data 모듈에 대한 유효한 후보가 됩니다.
- 도메인 클래스가 모듈 특정 유형 주석으로 주석이 달린 경우, 해당 Spring Data 모듈에 대한 유효한 후보가 됩니다. Spring Data 모듈은 JPA의 @Entity와 같은 타사 주석이나 Spring Data MongoDB 및 Spring Data Elasticsearch의 @Document와 같은 자체 주석을 허용합니다.
다음 예시는 모듈 특정 인터페이스(JPA인 경우)를 사용하는 저장소를 보여줍니다:
interface MyRepository extends JpaRepository<User, Long> { }
@NoRepositoryBean
interface MyBaseRepository<T, ID> extends JpaRepository<T, ID> { … }
interface UserRepository extends MyBaseRepository<User, Long> { … }
interface AmbiguousRepository extends Repository<User, Long> { … }
@NoRepositoryBean
interface MyBaseRepository<T, ID> extends CrudRepository<T, ID> { … }
interface AmbiguousUserRepository extends MyBaseRepository<User, Long> { … }
interface PersonRepository extends Repository<Person, Long> { … }
@Entity
class Person { … }
interface UserRepository extends Repository<User, Long> { … }
@Document
class User { … }
interface JpaPersonRepository extends Repository<Person, Long> { … }
interface MongoDBPersonRepository extends Repository<Person, Long> { … }
@Entity
@Document
class Person { … }
엄격한 저장소 구성을 위해 저장소 유형 세부 정보와 도메인 클래스 주석을 구별하는 것은 특정 Spring Data 모듈에 대한 저장소 후보를 식별하는 데 사용됩니다. 동일한 도메인 유형에 여러 영속성 기술 특정 주석을 사용하는 것이 가능하며, 이는 여러 영속성 기술에 걸쳐 도메인 유형의 재사용을 가능하게 합니다. 그러나 이 경우 Spring Data는 더 이상 저장소와 바인딩할 유일한 모듈을 결정할 수 없습니다.
저장소를 구별하는 마지막 방법은 저장소 기본 패키지의 범위를 지정하는 것입니다. 기본 패키지는 저장소 인터페이스 정의를 스캔하기 위한 시작점을 정의하며, 이는 적절한 패키지에 저장소 정의가 위치해야 함을 의미합니다. 기본적으로, 주석 기반 구성은 구성 클래스의 패키지를 사용합니다. XML 기반 구성에서는 기본 패키지가 필수입니다.
@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
class Configuration { … }
https://docs.spring.io/spring-data/jpa/reference/repositories/definition.html
Defining Repository Interfaces :: Spring Data JPA
To define a repository interface, you first need to define a domain class-specific repository interface. The interface must extend Repository and be typed to the domain class and an ID type. If you want to expose CRUD methods for that domain type, you may
docs.spring.io
'웹 > Spring' 카테고리의 다른 글
Reflection api GetMethod (0) | 2024.04.20 |
---|---|
Spring Data JPA - 구성 (0) | 2024.02.25 |
Spring Data JPA - 핵심 개념 (0) | 2024.02.03 |
Spring Data JPA에 대해서 (0) | 2024.02.03 |
톰캣의 war 실행되는 원리? (0) | 2024.01.14 |