이 포스트는 김영한 이사님의 스프링 입문 강의를 듣고 작성하였습니다.
이번에는 저번에 실습했던 JPA에서 더 나아가 이번엔 스프링 데이터 JPA에 대해서 다뤄보려고 한다. 스프링 데이터 JPA를 사용하면 구현클래스 없이 인터페이스 만으로도 반복적으로 개발해야됐던
CRUD 기능을 비롯하여 다른 기능들까지 아주 쉽게 구현할 수 있다고 한다.
실제 실무에서도 거의 필수라고 다뤄지고 있는 추세라고 하는데 이번에는 이에 대해서 다뤄보려고 한다.
이때 스프링 데이터 JPA는 JPA를 편하게 사용할 수 있도록 도와주는 도구일 뿐이기 때문에 먼저 JPA를 잘 학습한 후에 스프링 데이터 JPA를 구현하는 것을 권장한다고 한다.
기본세팅은 전에 진행했던 JpaMemberRepository와 동일하게 진행한다.
package memberpractice.memberpractice.repository;
import memberpractice.memberpractice.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long> , MemberRepository{
@Override
Optional<Member> findByName(String name);
}
SpringDataJpa를 사용할 땐 인터페이스로 구현된다.
놀랍게도 이렇게만 해줘도 우리가 구현하고자 했던 기능들이 모두 동작하게 된다.
JpaRepository를 상속받으면 SpringDataJpa가 자동으로 구현체를 만들어서 스프링 컨테이너에
스프링 빈으로 등록해준다.
package memberpractice.memberpractice;
import memberpractice.memberpractice.repository.*;
import memberpractice.memberpractice.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
@Autowired
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository);
}
// @Bean
// public MemberRepository memberRepository(){
// return new MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource);
// return new JdbcTemplateMemberRepository(dataSource);
// return new JpaMemberRepository(em);
// }
}
SpringDataJpa를 사용하는 경우 앞서 말했듯이 이미 JpaRepository를 상속받은 인터페이스에 대해 구현체를 자동적으로 생성해주고 스프링 빈으로 등록해주기 때문에 SpringConfig에서 바로 MemberRepository를 서비스에 주입해주면 된다.
역시 통합테스트가 정상적으로 잘 동작한 것을 확인할 수 있다.
위 사진은 인텔리제이를 활용하여 외부 라이브러리인 JpaRepository에 대해서 클래스 다이어그램으로 나타낸 것이다.
메서드를 살펴보면 findAll 혹은 save같은 CRUD기능까지 모든 리포지토리에 공통적으로 들어갈 수 있는 메서드들이 이미 존재하는 것을 확인할 수 있다.
이외에 공통적인 사항들이 아닌 리포지토리의 고유한 기능, 이 예와 같이 findByName같은 조회기능의 경우는 메서드 이름만으로도 구현이 가능하다. 이를 쿼리 메소드라고 하는데 SpringDataJpa의 쿼리 메소드에 대해서는 이 글을 참고하자.
지금까지 Jdbc, JdbcTemplate, JPA를 거쳐 Spring Data JPA까지 차근차근 알아보았다. 영상에서 다룬 바로는 실무에서는 JPA와 Spring Data JPA를 기본적으로 사용하고 복잡한 동적 쿼리는 Querydsl이라는 라이브러리를 사용하여 많이 작업한다고 한다.
JpaRepository의 클래스 다이어그램을 봤을 때 사실 제일 먼저 생각난 것이 drf의 Viewset이었다. 물론 viewset과 JpaRepository 두개를 놓고 보면 다른 점도 굉장히 많지만 공통적으로 들어가는 로직을 간편하게 처리할 수 있도록 도와준다는 것이 비슷하게 느껴졌다.
이제 스프링 입문 강의에 대한 정리도 거의 다 끝나간다. 생각보다 오래 걸렸었는데 듣고 따라치는데 그치는 것이 아닌 실제로 자료도 찾아보며 기존 강의의 내용에서 살을 붙여 정리하다보니 머릿속에 더 잘 남을 수 있었던 것 같다.
이렇게 정리하는 과정이 앞으로 스프링을 배워나가는데 있어 단단한 초석이 되었으면 좋겠다.