스프링 DB 접근 기술 - 스프링 데이터 JPA

Chooooo·2022년 8월 15일
0
post-thumbnail

스프링 데이터 JPA

스프링 DB 접근 기술의 마지막 단계인 스프링 데이터 JPA.
스프링부트와 JPA만을 사용해도 개발해야할 코드가 확연히 줄고, 개발 생산성 또한 많이 증가한다. 여기서 스프링 데이터 JPA를 사용하면 리포지토리 구현 클래스 없이 인터페이스만을 작성하여 개발을 완료할 수 있어.
특히 기본 CRUD 기능을 스프링 데이터 JPA가 제공한다.
스프링부트, JPA와 더불어서 스프링 데이터 JPA라는 프레임워크를 더하면 개발이 즐거워진다(쉬워진다..?_)
따라서 개발자는 단순하고 반복적인 코드를 작성하지 않아도 되고, 핵심 비즈니스 로직을 구현하는데에만 집중할 수 있어.
주의해야할 사항은 스프링 데이터 JPA는 JPA를 편리하게 사용하도록 도움을 주는 기술이므로, JPA에 대해 먼저 학습한 후 이를 학습해야 한다!!!!

(실무에서 관계형 데이터베이스를 사용한다면, 스프링 데이터 JPA는 필수이다.)

설정

스프링 데이터 JPA를 사용하기 위해서는 앞에서 설정했던 JPA설정 그대로 사용할꺼야
src/main/java/프로젝트/repository에 인터페이스를 만든다.
지금까지와 다르게 "인터페이스"를 만든다는 것에 유의하면서...

respository폴더에 SpringDataJpaMemberRepository 인터페이스 파일을 생성하고 아래 코드 작성.

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{
    @Override
    Optional<Member> findByName(String name);
}

SpringDataJpaMemberRepository 인터페이스는 스프링 데이터 JPA에서 제공하는 JpaRepository를 받는다. 이때 저장되는 Member 클래스와 PK의 타입인 Long을 명시해주고, JpaRepository와 같이 MemberRepository또한 받는다.
findByName()메서드만 인터페이스를 생성

  • 인터페이스가 인터페이스를 받을 때는 implements가 아니라 extends를 사용!
    (인터페이스는 다중 상속 가능하잖아)

중요 원리

JpaRepository를 상속받은 인터페이스는 스프링 데이터 JPA가 그 구현체를 자동으로 만들고 스프링 빈에 등록해준다.
즉 내가 이 SpringDataJpaMemberRepository를 구현하고 스프링 빈에 등록할 필요가 없다. 그 구현체를 가져다 쓰면 되기 때문!!!

코드 수정

package hello.hellospring;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.*;
import hello.hellospring.service.MemberService;
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 DataSource dataSource;
    //private final EntityManager em;
    
    private final MemberRepository memberRepository;

    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);
//    }
}
  • 생성자에 주입되는 MemberRepository는 스프링 데이터 JPA가 자동으로 만들어 둔 인터페이스 SpringDataJpaMemberRepository의 구현체이다.
    게다가 MemberRepository를 다중 상속 받았기 때문에 MemberRepository로 주입될 수 있는 것.

다시 말해서, 이렇게 단순히 인터페이스만을 생성하여 동작이 가능한 것은 인터페이스를 생성할 때 JpaRepository를 extends했기 때문. 해당 인터페이스를 내려받으면 스프링 데이터 JPA에서 자동으로 인터페이스의 구현체를 만들고, 스프링 빈으로 자동으로 등록한다.
우리는 자동으로 등록된 회원 리포지토리 스프링 빈을 SpringConfig에서 회원 서비스에 주입, 이를 사용하였다.

해당 로직 테스트해보면 잘 동작해!

스프링 데이터 JPA의 제공 기능

스프링 데이터 JPA가 제공하는 클래스를 확인해보자

  • 인터페이스를 통한 기본적인 CRUD
    --> 우리가 생각할 수 있는 대부분의 생성, 조회, 수정, 삭제 메서드를 제공한다.

  • findByName(), findByEmail()처럼 메서드 이름 만으로 조회 기능 제공한다.

  • 페이징 기능 자동 제공한다.

실무에서는 JPA와 스프링 데이터 JPA를 기본으로 사용하고, 복잡한 동적 쿼리는 Querydsl이라는 라이브러리를 사용하면 된다. Querydsl을 사용하면 쿼리도 자바 코드로 안전하게 작성할 수 있고, 동적 쿼리도 편리하게 작성할 수 있다. 이 조합으로 해결하기 어려운 쿼리는 JPA가 제공하는 네이티브 쿼리를 사용하거나 스프링 JdbcTemplate를 사용하면 된다.

profile
back-end, 지속 성장 가능한 개발자를 향하여

0개의 댓글