스프링 데이터 JPA는 JPA를 편리하게 도와주는 기술, 라이브러리이다. 스프링 부트와 JPA만 사용해도 개발 생산성이 많이 증가한다. 개발 코드도 확연히 줄어든다. 여기에 스프링 데이터 JPA를 사용하면 리포지토리에 구현 클래스 없이 인터페이스 만으로 개발을 완료할 수 있다. 반복 개발해온 아주 기본적인 CRUD 기능도 스프링 데이터 JPA가 모두 제공한다. 즉, 개발자는 핵심 비즈니스 로직을 개발하는 데 집중할 수 있다.
1. 스프링 데이터 JPA로 이름찾기
놀랍게도 2개의 인터페이스를 상속받고, 아래 1줄의 코드로 이름을 찾는다.
JpaRepository는 내가 만들어 놓은 인터페이스가 아닌 라이브러리를 쓴 것이다.
분명 아래 코드는 인터페이스이지만, JpaRepository를 받고 있으면 구현체를 자동으로 만들어준다. 그리고 프록시 기술을 사용해 스프링빈에 등록까지 해준다. 우리는 그걸 그냥 가져다쓰면 된다.
package com.hello.hellospring.repository;
import com.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);
}
2. 설정 변경
1) JPA 사용 시 코드
package com.hello.hellospring;
import com.hello.hellospring.repository.JdbcMemberRepository;
import com.hello.hellospring.repository.JpaMemberRepository;
import com.hello.hellospring.repository.MemberRepository;
import com.hello.hellospring.repository.MemoryMemberRepository;
import com.hello.hellospring.service.MemberService;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
@PersistenceContext
private EntityManager em;
@Autowired
public SpringConfig(EntityManager em){
this.em = em;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
// return new MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource); //데이터베이스 교체
return new JpaMemberRepository(em);
}
}
2) 스프링 데이터 JPA 사용 시 코드
인터페이스 그 자체를 주입받는다.
package com.hello.hellospring;
import com.hello.hellospring.domain.Member;
import com.hello.hellospring.repository.JdbcMemberRepository;
import com.hello.hellospring.repository.JpaMemberRepository;
import com.hello.hellospring.repository.MemberRepository;
import com.hello.hellospring.repository.MemoryMemberRepository;
import com.hello.hellospring.service.MemberService;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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);
}
// @Bean
// public MemberRepository memberRepository(){
//// return new MemoryMemberRepository();
//// return new JdbcMemberRepository(dataSource); //데이터베이스 교체
// return new JpaMemberRepository(em);
// }
}
3. 스프링 데이터 JPA 제공 클래스
하지만 비즈니스 로직에서 항상 똑같이 Name 이름으로 회원을 찾는 법은 없다. 이메일, 아이디 등 내가 설계한 비즈니스 로직에 따라 다르기 때문에 공통 클래스를 제공하기 어렵다. 그래서 스프링 데이터 JPA는 규칙을 짰다.
package com.hello.hellospring.repository;
import com.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);
}
만약 위처럼 findByName을 한다면, JPQL로 다음과 같이 변경된다.
select m from Member m where m.name = ?;
만약 Name 뒤에 And나 Or을 붙이고, Id를 붙인다면, 다음과 같이 JPQL이 구성된다.
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository{
@Override
Optional<Member> findByNameAndId(String name, Long Id);
}
select m from Member m where m.name = ? and m.id = ?;
심지어 페이징 기능까지 자동으로 제공한다.
이런 방식으로 인터페이스만으로도 개발을 끝낼 수 있는 것이다.
'BE > Spring' 카테고리의 다른 글
Spring 변경사항 자동 반영 (0) | 2024.01.10 |
---|---|
AOP(Aspect Oriented Programming) (0) | 2024.01.09 |
데이터베이스 스프링에 연결하기 (2. JPA 방식) (0) | 2024.01.05 |
데이터베이스 스프링에 연결하기 (1. 순수 JDBC 방식), DI와 OCP (0) | 2024.01.05 |
h2 실습용 데이터베이스 실행 방법 (0) | 2024.01.05 |