데이터 접근 계층 개발의 문제
- 대부분의 데이터 접근 계층(DAO)은 CRUD라고 부르는 유사한 등록, 수정, 삭제 조회 코드를 반복해서 개발해야 하는데
JPA를 사용해서 데이터 접근 계층을 개발할 때도 이 같은 문제가 발생 - 이러한 반복 문제를 해결하려면 제네릭과 상속을 적절히 사용해서 공통 부분을 처리하는 부모 클래스인 GenericDAO를 만듦
하지만 이 방법은 공통 기능을 구현한 부모 클래스에 너무 종속되고 구현 클래스 상속이 가지는 단점이 노출됨
// JPA의 반복적인 CRUD
public class MemberRepository {
@PersistenceContext
EntityManager em;
public void save(Member member) {...}
public Member findOne(Long id) {...}
public List<Member> findAll() {...}
public Member findByUsername(String username) {...}
}
스프링 데이터 JPA 소개
- 스프링 프레임워크에서 JPA를 편리하게 사용할 수 있도록 지원하는 프로젝트로
데이터 접근 계층을 개발할 때 지루하게 반복되는 CRUD 문제를 세련된 방법을 해결 - 우선 CRUD를 처리하기 위한 공통 인터페이스를 제공하므로
리포지토리를 개발할 때 인터페이스만 작성하면 실행 시점에 스프링 데이터 JPA가 구현 객체를 동적으로 생성해서 주입해줌
그러므로 데이터 접근 계층을 개발할 때 구현 클래스 없이 인터페이스만 작성해도 개발을 완료할 수 있음 - 일반적인 CRUD 메소드는 JpaRepository 인터페이스가 공통으로 제공하므로 문제가 없지만
MemberRepository.findByUsrname(...)처럼 직접 작성한 공통으로 처리할 수 없는 메소드는
스프링 데이터 JPA가 메소드 이름을 분석해서 JPQL을 실행
// 스프링 데이터 JPA 적용
/* CRUD를 처리하기 위한 공통 메소드는 스프링 데이터 JPA가 제공하는 JpaRepository 인터페이스에 존재
회원 리포지토리 인터페이스의 구현체는 애플리케이션 실행 시점에 스프링 데이터 JPA가 생성해서 주입해줌
따라서 개발자가 직접 구현체를 개발하지 않아도 됨 */
public interface MemberRepository extends JpaRepository<Member, Long> {
Member findByUsername(String username);
// select m from Member m where usernmae = :username
}
- 스프링 데이터 프로젝트
스프링 데이터 JPA는 스프링 데이터 프로젝트의 하위 프로젝트 중 하나
스프링 데이터 프로젝트는 다양한 데이터 저장소에 대한 접근을 추상화해서
개발자 편의를 제공하고 지루하게 반복하는 데이터 접근 코드를 줄여줌
여기서 스프링 데이터 JPA 프로젝트는 JPA에 특화된 기능을 제공하며,
스프링 프레임워크와 JPA를 함께 사용한다면 스프링 데이터 JPA 사용을 적극 추천
스프링 데이터 JPA 설정
- 필요 라이브러리
스프링 데이터 JPA는 spring-data-jpa 라이브러리가 필요
// 스프링 데이터 JPA 메이븐 라이브러리 설정
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
- 환경설정
스프링 설정에 XML을 사용하면 <jpa:respositories>를 사용하고 리포지토리를 검색할 base-package를 적으면
해당 패키지와 그 하위 패키지를 검색
// XML 설정
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="jpabook.jpashop.repository" />
</beans>
- JavaConfig 설정
스프링 설정에 JavaConfig를 사용하면 EnableJpaRepositories 어노테이션을 추가하고
basePackage에는 리포지토리를 검색할 패키지 위치를 적음
// JavaConfig 설정
@Configuratrion
@EnableJpaRepositories(basePackage = "jpabook.jpashop.repository")
public class AppConfig {}
- 스프링 데이터 JPA 동작 과정
애플리케이션을 실행할 때 basePackage에 있는 리포지토리 인터페이스들을 찾아서
해당 인터페이스를 구현한 클래스를 동적으로 생성한 다음 스프링 빈에 등록함
따라서 개발자가 직접 구현 클래스를 만들지 않아도 됨
공통 인터페이스 기능
- 스프링 데이터 JPA는 간단한 CRUD 기능을 공통으로 처리하는 JpaRepository 인터페이스를 제공하므로
스프링 데이터 JPA를 사용하는 가장 단순한 방법은 이 인터페이스를 상속받는 것이며
그 후 제네릭에 엔티티 클래스와 엔티티 클래스가 사용하는 식별자 타입을 지정하면 됨 - 예) 상속받은 JpaRepository<Member, Long> 부분을 보면 제네릭에 회원 엔티티와 회원 엔티티의 식별자 타입을 지정했음
이제부터 회원 리포지토리는 JpaRepository 인터페이스가 제공하는 다양한 기능을 사용할 수 있음
// JpaRepository 공통 기능 인터페이스
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
...
}
// JpaRepository를 사용하는 인터페이스
public interface MemberRepository extends JpaRepository<Member, Long> {
}
- JpaRepository 인터페이스의 계층 구조
윗 부분에 스프링 데이터 모듈이 있고 그 안에 Repository, CrudRepository, PagingAndSortingRepository가 존재
이들은 스프링 데이터 프로젝트가 공통으로 사용하는 인터페이스로
스프링 데이터 JPA가 제공하는 JpaRepository 인터페이스는 여기에 추가로 JPA가 특화된 기능을 제공
JpaRepository 인터페이스를 상속 받으면 사용할 수 있는 주요 메소드로
JpaRepository 공통 인터페이스를 사용하면 일반적인 CRUD를 해결할 수 있음
여기에서 T는 엔티티, ID는 엔티티의 식별자 타입, S는 엔티티와 그 자식 타입을 뜻함
- save(S)
엔티티에 식별자가 없으면 EntityManager.persist()를 호출하여 새로운 엔티티는 저장하고
식별자 값이 있으면 이미 있는 엔티티로 판단해서 EntityManager.merge()를 호출하여 수정 - delete(T)
엔티티 하나를 삭제하며, 내부에서 EntityManager.remove()를 호출 - findOne(ID)
엔티티 하나를 조회하며, 내부에서 EntityManager.find()를 호출 - getOne(ID)
엔티티를 프록시로 조회하며, 내부에서 EntityManager.getReference()를 호출 - findAll(...)
모든 엔티티를 조회하며, 정렬이나 페이징 조건을 파라미터로 제공할 수 있음
- save(S)
'Java-Spring > 자바 ORM 표준 JPA 프로그래밍' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍] 스프링 데이터 JPA ③ (0) | 2022.05.18 |
---|---|
[자바 ORM 표준 JPA 프로그래밍] 스프링 데이터 JPA ② (0) | 2022.05.17 |
[자바 ORM 표준 JPA 프로그래밍] 웹 애플리케이션 제작 ③ - 애플리케이션 구현 (0) | 2022.05.15 |
[자바 ORM 표준 JPA 프로그래밍] 웹 애플리케이션 제작 ② - 도메인 모델과 테이블 설계 (0) | 2022.05.12 |
[자바 ORM 표준 JPA 프로그래밍] 웹 애플리케이션 제작 ① - 프로젝트 환경설정 (0) | 2022.05.12 |