스프링 데이터 JPA-06.리포지토리(스프링 데이터 Common)
구분 | 설명 |
---|---|
스프링 데이터 | SQL & NoSQL 저장소 지원 프로젝트의 묶음. |
스프링 데이터 Common | 여러 저장소 지원 프로젝트의 공통 기능 제공. |
스프링 데이터 REST | 저장소의 데이터를 하이퍼미디어 기반 HTTP 리소스로(REST API로) 제공하는 프로젝트. |
스프링 데이터 JPA | 스프링 데이터 Common이 제공하는 기능에 JPA 관련 기능 추가. |
이 외에도 스프링 데이터 MongoDB, Redis, KeyValue.. 다양한 프로젝트 존재
http://projects.spring.io/spring-data/
스프링 데이터 Common 1. 리포지토리
public class PostRepository extends JpaRepository<Post, Long> { JpaRepository를 상속. 이를 확인해 보면..
@NoRepositoryBean // 이 리파지토리를 상속받았기 때문에 스프링 데이터 JPA 등.. 다른 것들을 상속받았을 때, 빈을 생성하지 않게 하기 위해서
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
PagingAndSortingRepository, QueryByExampleExecutor 등
PagingAndSortingRepository 를 타고 확인해보면..
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort); // 정렬(sort)
Page<T> findAll(Pageable pageable); // 페이징
}
PagingAndSortingRepository : 정렬, 페이징 지원
CrudRepository : 기본 crud 메서드 지원
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity);
<S extends T> Iterable<S> saveAll(Iterable<S> entities);
Optional<T> findById(ID id);
boolean existsById(ID id);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> ids);
long count();
void deleteById(ID id);
void delete(T entity);
void deleteAll(Iterable<? extends T> entities);
void deleteAll();
}
// 실제 소스에는 주석 달려있어서 확인 가능. 직접 확인 가능하니 포스팅에는 간추린 것.
(또한 메서드 명으로 대부분 유추가 가능)
Repository : 마커 역할, 기능이 존재하지는 않음.
직접 타고 들어가보면서 어떤 기능들이 구현되어 있는지 확인할 수 있다.
실습
이미 스프링에서 검증이 되어서 제공을 하는 거지만, 학습을 위해 테스트 작성
@ExtendWith(SpringExtension.class)
@DataJpaTest
class PostRepositoryTest {
@Autowired
PostRepository postRepository;
// 테스트는 h2 사용, 의존성 확인
@Test
public void curdRepository(){
Post post = new Post();
post.setTitle("hello spring boot common");
assertNull(post.getId());
Post newPost = postRepository.save(post);
assertNotNull(newPost.getId());
List<Post> posts = postRepository.findAll();
assertEquals(posts.size(), 1);
assumeTrue(posts.contains(post));
Page<Post> page = postRepository.findAll(PageRequest.of(0, 10));
assertEquals(page.getTotalElements(), 1); // 총 개수
assertEquals(page.getNumber(), 0); // 현재 페이지 넘버
assertEquals(page.getSize(), 10); // 페이지 사이즈
}
}
커스터 마이징
public interface PostRepository extends JpaRepository<Post, Long> {
Page<Post> findByTitleContains(String title, Pageable pageable);
}
...
Post post2 = new Post();
post2.setTitle("test");
postRepository.save(post2);
Page<Post> page2 = postRepository.findByTitleContains("spring", PageRequest.of(0, 10));
assertEquals(page2.getTotalElements(), 1); // 총 개수
assertEquals(page2.getNumber(), 0); // 현재 페이지 넘버
assertEquals(page2.getSize(), 10); // 페이지 사이즈
...
1개 더 추가했는데, spring 이 들어간 게시글만 참조해서 1개에서 테스트가 성공하는 걸 볼 수 있다.
추후 더 자세하게 정리 예정