스프링 부트와 JPA만 사용해도 개발 생산성이 증가하지만 스프링 데이터 JPA를 사용하면 리포지토리 구현없이 인터페이스 만으로 개발이 가능합니다. 따라서 개발자는 핵심 비지니스 로직 개발에만 집중할 수 있습니다.
일단 SpringDataJpaRepository를 만듭니다. (인터페이스만 구현합니다.)
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>,MemberRepository
{
Optional<Member> findByName(String name);
}
단순한 인터페이스 입니다. springConfig파일을 수정해줍니다.
package hello.hellospring;
import hello.hellospring.repository.*;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
@Autowired // 생략 가능
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository);
}
}
Spring container에서 bean에 등록된 repository를 찾는다. 하지만 현재 등록되어 있는 것은 인터페이스입니다. 인터페이스를 만들고 extends JpaRepository
를 사용하였으므로 인터페이스에 대한 구현체를 알아서 만들어줍니다.
일단 위에서 만든 기능이 잘 동작하는지 살펴봅시다.
통합 테스트는 잘 통과하는 것을 볼 수 있습니다. 야호~
다음과 같은 공통화된 메서드들을 모두 제공해줍니다. 심지어 이름으로 어느정도 메서드를 만들 수 있습니다. 예를 들어 인터페이스에
Optional<Member> findByNameAndId(String name, Long id);
이런식으로 작성하면 인터페이스 이름으로 개발이 된다. 물론 복잡한 메서드는 다른 해결 방법이 있다고 합니다.