Spring Data Repository 추상화
RepositoryItemReader
RepositoryItemReader를 사용하면 다른 레포지터리의 기능을 추상화하여 사용할 수 있다.
JpaRepository, MongoRepository, Neo4jRepository 등
- 페이징 방식으로 동작하기에 반드시
PagingAndSortingRepository를 상속해야 한다.
- 아래는
ElasticSearch에서 데이터를 읽는 Repository 예이다.
interface HackNoteRepository : ElasticsearchRepository<HackNote, String> {
fun searchNotesByMessageAndSentimentIsNull(keyword: String, pageable: Pageable): Page<HackNote>
}
fun reader(): RepositoryItemReader<HackNote> =
RepositoryItemReaderBuilder<HackNote>()
.name("hackNoteItemReader")
.repository(hackNoteRepository)
.methodName("searchNotesByMessageAndSentimentIsNull")
.arguments(mutableListOf<String>("PWN"))
.pageSize(10)
.sorts(mapOf("timestamp" to Sort.Direction.DESC))
.build()
repository
- 사용할 Spring Data Repository를 지정
methodName
Repository에서 호출할 메서드 이름 지정
arguments
- 전달한 인자를 리스트로 지정
Pageable 객체는 pageSize, sorts 메서드로 전달한 값으로 자동으로 생성된다.
pageSize
sorts
RepositoryItemReader는 PagingAndSortingRepository를 사용하기에 오프셋 방식의 페이징을 사용한다. 데이터가 많아질수록 성능에 주의해야 한다.
RepositoryItemWriter
RepositoryItemWriter는 CrudRepository의 저장 기능을 사용한다.
- 페이징을 하지 않기에
PagingAndSortingRepository일 필요가 없다.
- 기본적으로
saveAll 메서드로 아이템들을 저장한다.
@Bean
fun logWriter(): RepositoryItemWriter<HackNote> {
return RepositoryItemWriterBuilder<HackNote>()
.repository(hackNoteRepository)
.methodName("save")
.build()
}
methodName
- 지정하면
saveAll 외의 다른 메서드가 호출된다.
- 웬만한 구현체들의
saveAll은 효율적인 벌크 연산을 지원하기에 특별한 경우가 아니면 지정하지 않아도 된다.