개발일기
스프링 데이터 JPA 본문
CRUD 기능도 스프링 데이터 JPA가 모두 제공한다.
스프링부트와 JPA라는 기반 위에, 스프링 데이터 JPA라는 환상적인 프레임워크를 더하면 개발이 정말 즐거워진다.
실무에서 관계형 데이터베이스를 쓰면 Spring Data JPA는 선택이 아니라 필수이다.
주의:) 처음부터 스프링 데이터 JPA를 배우는 경우가 있는데 이것은 큰일 날 수도 있음.
SpringDataJPA는 JPA를 편리하게 사용하도록 도와주는 기술이다. 따라서 JPA를 먼저 학습한 후에 스프링 JPA를 학습해야 한다.
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);
}
JpaRepository도 인터페이스지만 인터페이스가 인터페이스를 가져올 때는 extends를 통해서 가져온다.
JpaRepository<타입, 키> <- 키에는 id가 들어가야 하는데 여기서 id의 타입은 long이기 때문에 long을 집어 넣어준다. Type은 당연히 Member일 것이다. 인터페이스는 다중 상속이 가능하다.
이렇게 하면 다 만든거라고 한다.. 구현한 부분이 없는데 다만들었다..
인터페이스만 있고 신기한게 구현체는 없다.
인터페이스만 있는데 이렇게하면 스프링 데이터 JPA가 JpaRepository를 가지고 있으면 구현체를 자동으로 만들어준다. 그래서 스프링 빈에 자동으로 등록을 해줌.
내가 스프링빈에 등록을 하는게 아니라 SpringDataJpa가 여기 이런게 있네 하고 자동으로 SpringBean에 등록을 해준다.
우리는 이것을 그냥 가져다가 쓰면된다.
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 EntityManager em;
private final MemberRepository memberRepository;
@Autowired
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
//@Autowired
// public SpringConfig(EntityManager em) {
// this.em = em;
//}
// private DataSource dataSource;
// @Autowired
// public SpringConfig(DataSource dataSource) {
// this.dataSource = dataSource;
// }
@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);
//}
}
Spring Config 코드를 우리가 써야하는 것으로 바꿔주었다.
injection을 받으면 된다. 그러면 Spring Data를 만들어 놓은 구현체로 등록이 된다.
그리고 memberService에다가 의존관계를 세팅을 해주어야 한다.
이런 경우에는 Spring Container에서 memberRepository를 찾는다. 그런데 내가 등록한게 없음.
그런데 우리는 하나가 있긴 있음. SpringDataJpaMemberRepository이다.
SpringData가 인터페이스에 대한 구현체를 그냥 지가 기술을 가지고 만들어 낸다. 그 후 스프링 빈에 등록을 해놓는다.
이렇게 하면 끝난다.
이 정도만 해도 진짜로 작동을 한다.
동작 설명)
먼저 SpringDataJpa가 SpringDataJpaMemberRepository를 만든다. 프롭시라는 기술이 있는데 이걸 가지고 어떻게 객체를 생성해서 Spring Bean에 올린다. 우리는 이걸 인젝션하여 사용한 것이다.
Save나 이런것들은 다 스프링 데이터에 있다.
들어가보면 뭔가 기본 메소드들이 다 제공되고 있다. 기본적인 CRUD랑 단순 조회들은 다 제공이 된다.
가끔 못 만드는 것들도 있다. 모두에게 통용되는 것말고 개인적으로 만들어야하는 쿼리들이나 이런것들은 직접 만들어야 한다. 비즈니스마다 다르기 때문에 공통으로 만들어둘 수가 없기 때문에 직접 만들어야한다.
그래서 SpringDataJpa에서 Optional<Member> findByName(String name)이런식으로 만들어 준것이다.
<- 이것을 만들어 주기 위해서 JPQL 쿼리는 select m from Member m where m.name = ? 이런식으로 작성한다.
참고: 실무에서는 JPA와 스프링 데이터 JPA를 기본으로 사용하고, 복잡한 동적 쿼리는 Querydsl이라는 라이브러리를 사용하면 된다. Querydsl을 사용하면 쿼리도 자바 코드로 안전하게 작성할 수 있고, 동적 쿼리도 편리하게 작성할 수 있다. 이 조합으로 해결하기 어려운 쿼리는 JPA가 제공하는 네이티브 쿼리를 사용하거나, 앞서 학습한 스프링 JdbcTemplate를 사용하면 된다
'Spring > Spring tutorial - 코드로 배우는 스프링 (김영한)' 카테고리의 다른 글
AOP적용 (1) | 2022.10.05 |
---|---|
AOP가 필요한 상황 (1) | 2022.10.05 |
JPA (1) | 2022.10.05 |
스프링 JdbcTemplate (0) | 2022.09.30 |
스프링 통합 테스트 (1) | 2022.09.30 |