2세/JPA

[Spring Data JPA] 순수 JPA와 Spring Data JPA

코딩러버 2024. 2. 27. 11:39
728x90
순수한 JPA 기반 Repository를 구현했을 때와 Spring Data Jpa 기반으로 구현했을 때를 비교해 본다.

 

순수 JPA

@Repository
public class MemberJpaRepository {

    @PersistenceContext
    private EntityManager em;

    public Member save(Member member) {
        em.persist(member);
        return member;
    }

    public void delete(Member member) {
        em.remove(member);
    }

    public List<Member> findAll() {
        return em.createQuery("select m from Member m", Member.class)
                .getResultList();
    }

    public Optional<Member> findById(Long id) {
        Member member = em.find(Member.class, id);
        return Optional.ofNullable(member);
    }

    public long count() {
        return em.createQuery("select count(m) from Member m", Long.class)
                .getSingleResult();
    }

    public Member find(Long id) {
        return em.find(Member.class, id);
    }
}

 

member를 저장하고 단건, 리스트 조회, 삭제 등 CRUD를 개발자가 구현한다.

여기서 문제는 member가 아닌 team에 대한 CRUD 또한 거의 동일하게 일일이 구현해주어야 하는데

중복되는 코드들도 많으며 개발하는 데에 번거로움 또한 커진다.

 

Spring Data JPA

공통 인터페이스 설정

@Configuration
@EnableJpaRepositories(basePackages = "jpabook.jpashop.repository")
public class AppConfig {} @EnableJpaRepositories

@EnableJpaRepositories

  • Spring 프레임워크에서 제공하는 어노테이션 중 하나로, JPA 리포지토리를 활성화
  • basePackages 속성을 통해 JPA 리포지토리 인터페이스를 포함한 패키지를 지정할 수 있다.
  • 이렇게 지정된 패키지 내의 JPA 리포지토리 인터페이스는 스프링이 자동으로 구현체를 생성하고 관리한다.

SpringBoot 사용 시에는 생략이 가능하다.

@SpringBootApplication
public class DataJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(DataJpaApplication.class, args);
    }

}

@SpringBootApplication로 위치를 지정한다. (해당 패키지와 하위 패키지를 인식해 줌)

 

public interface MemberRepository extends JpaRepository<Member, Long> {
}

Spring Data Jpa가 대신 구현클래스를(proxy 객체) 생성하고 관리해 주어 개발자가 직접 구현하지 않아도 된다.

때문에 굉장히 코드가 간략하다.

 

더하여 @Repository를 달아주지 않아도 컴포넌트 스캔을  Spring Data Jpa가 자동으로 인식하여 처리해준다.