Spring Data는 여러 가지 프로젝트로 되어 있다. 그중에서 Common 프로젝트에 대해서 알아보자.
Spring Data는 여러개의 프로젝트로 구성되어 있다. 그 중에서 JPA에서 공통으로 사용하는 Common 프로젝트에 대해서 알아보자. (물론 다른 Redis,MongoDb 저장소에서도 공통으로 사용하니까 Common으로 따로 뺀 것)
Repository 상속 관계
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
실제 특정 엔티티의 Repository를 구성할 때 다음과 같이 JpaRepository 인터페이스를 상속받아서 사용했다.
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    List<T> findAll();
    List<T> findAll(Sort var1);
    List<T> findAllById(Iterable<ID> var1);
    ...
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
    Iterable<T> findAll(Sort var1);
    Page<T> findAll(Pageable var1);
}
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S var1);
    <S extends T> Iterable<S> saveAll(Iterable<S> var1);
    Optional<T> findById(ID var1);
    boolean existsById(ID var1);
    Iterable<T> findAll();
    ...
@Indexed
public interface Repository<T, ID> {
Repository 구조
Repository
CrudRepository
PagingAndSortRepository
=========================  ▲ 위에 부분이 Common 프로젝트 부분
JpaRepository
PostRepository
다음과 같이 상속 구조를 가지고 있다. 최상위 Repository는 마커용으로 아무 의미도 없다.
CrudRepository는 엔티티의 기본적인 crud를 담당. 페이징관련된 부분은 PagingAndSortRepository가 담당한다.
예제 코드
Post 엔티티를 만들고 @DataJpaTest 슬라이싱 테스트를 해보자. 슬라이싱 테스트를 하는 이유는 Repository 관련 된 빈만 등록하기 때문에 시간을 절약한다.
@Data
@Entity
@Table
@ToString
public class Post {
    @Id
    @GeneratedValue
    private Long id;
    private String title;
    ...
}
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>
테스트용 h2 데이터베이스를 사용한다.
테스트 케이스
@RunWith(SpringRunner.class)
@DataJpaTest //레포지토리 관련된 빈만 등록하는 슬라이싱 테스트 (통합테스트와 다름)
public class JpaTest {
    @Autowired
    private PostRepository postRepository;
    @Test
    public void crudTest() {
        Post post = new Post();
        post.setTitle("new Post");
        Post retrivedPost = postRepository.save(post);
        Assert.assertNotNull(retrivedPost);
        List<Post> allPost = postRepository.findAll();
        Page<Post> page = postRepository.findAll(PageRequest.of(0, 10));
        Assert.assertEquals(page.getTotalElements(), 1); // 전체 데이터 개수
        Assert.assertEquals(page.getTotalPages(), 1); //전체 페이지
        Assert.assertEquals(page.getNumber(), 0); //시작 페이지 0부터 시작
        Assert.assertEquals(page.getSize(), 10); //페이지의 컨텐츠 사이즈 10개 단위로 끊음
        System.out.println(page.getContent()); // [Post(id=1, title=new Post, comments=[])]
findAll() 메서드는 파라미터가 없는 경우에 전체 엔티티를 조회하지만(실제 업무에서 거의 쓰이지 않음, 테스트 용도를 제외하고) 인자로 Pageable를 넘기는 경우에는 페이징에 맞게 데이터를 조회할 수 있다.
    Page<T> findAll(Pageable pageable);
📚 Related Posts
- Spring WebFlux 테스트 방법
 - Spring과 MongoDB 연동 실전 가이드
 - SpringBoot, MongoDB 시작하기
 - Spring Boot 서버 타임존 설정 방법
 - SpringBoot CommandLineRunner, ApplicationRunner 초기화 방법
 - Jackson, LocalDateTime Serialization, Deserialization 이슈
 - Spring Boot, Dockerfile로 이미지 생성, 배포하기
 - SpringBoot RabbitMQ 연동하기
 - Junit5 정리
 - Spring Sentry(에러 트래킹 서비스) 적용하기
 - [Spring] 빈 주입하는 방법 && Best Practice
 - Thymeleaf 실무에서 자주 사용하는 것들
 - Thymeleaf Collection 정보 화면에 렌더링하기
 - Spring, JPA를 이용한 REST API 만들기
 - [Spring] MultipartFile을 이용한 파일 업로드
 - [Spring] 모델 검증(validation)
 - [Spring]HandlerMethodArgumentResolver 인터페이스
 - [Spring] DispatcherServlet에 대해서 알아보자
 - [Spring] MVC 만들어 보기
 - [Spring] 메세지 컨버터
 - [Spring] MVC 살펴보기
 - [Spring] @ConfigurationProperties를 이용해서 properties값들을 클래스로 관리하기
 - [Spring] Profile 설정하기
 - [Spring] SpringApplication를 통한 코딩
 - [Spring Boot] 스프링 부트 3가지 특징
 - [Spring] @SpringBootAppllication 어노테이션에 대한 고찰
 - [Spring] bean circular dependencies (빈 순환 참조)
 - [Spring]Bean에 대해서 알아보자
 - SpringBoot, JPA, H2를 이용한 간단한API 작성
 - [Spring] Spring Data Common 프로젝트 살펴보기