JPA는 기존의 반복 코드는 물론, 기본적인 SQL도 JPA가 직접 만들어 실행해준다.
JPA를 사용하면 SQL과 데이터 중심 설계에서 객체 중심의 설계로 패러다임을 전환할 수 있으며, 개발 생산성을 크게 높일 수 있다.
라이브러리 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
@Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class JpaMemberRepository implements MemberRepository {
private final EntityManager em;
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
@Override
public Member save(Member member) {
em.persist(member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
}
@Override
public Optional<Member> findByName(String name) {
List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class)
.setParameter("name", name)
.getResultList();
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
}
em.find()
findByName()
이나 findAll()
과 같은 pk 기반이 아닌 나머지들은 JPQL을 작성해주어야 함. ex) em.createQuery("select m from Member m", Member.class)
@Transactional
import org.springframework.transaction.annotation.Transactional
@Transactional
public class MemberService {}
JPA를 사용하도록 스프링 설정 변경
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
private EntityManager em;
@Autowired
public SpringConfig(EntityManager em) {
this.em = em;
}
@Autowired
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository);
}
@Bean
public MemberRepository memberRepository() {
return new JpaMemberRepository(em);
}
}
스프링 데이터 JPA를 사용하면, 기존의 한계를 넘어 마치 마법처럼, 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있다. 반복 개발해온 기본 CRUD 기능도 스프링 데이터 JPA가 모두 제공한다.
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {
//JPQL select m from Member m where m.name = ?
@Override
Optional<Member> findByName(String name);
}
extends JpaRepository<객체, id>, MemberRepository
스프링 데이터 JPA 회원 리포지토리를 사용하도록 스프링 설정 변경
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
@Autowired
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository);
}
}
SpringDataJpaMemberRepository
를 스프링 빈으로 자동 등록해준다.findByName()
, findByEmail()
처럼 메서드 이름만으로 조회하는 기능 제공✒️ 스프링 데이터 JPA를 처음 알았을 때, 나는 엄청난 신기술을 처음 접한 사람마냥 놀라워했다. 이를 사용함으로써 지금까지 조금이라도 단순하고 반복이라 생각했던 개발 코드들이 확연하게 줄어들며, 개발이 즐거워지도록 도와준다. 스프링 데이터 JPA는 정말 편리하고 환상적인 프레임워크이다.. 따라서 개발자는 핵심 비즈니스 로직을 개발하는 데 집중할 수 있다.
[출처] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 / 김영한 https://inf.run/WzVy