13. 스프링 데이터 JPA


스프링 데이터 JPA?

  • 스프링 프레임워크에서 JPA를 편하게 사용할 수 있도록 지원하는 프로젝트
  • 데이터 접근 계층(repository)를 인터페이스만 작성해도 런타임 시에 스프링 데이터 JPA가 구현 객체를 주입해줌
  • 즉, 구현 클래스를 직접 작성하지 않고 인터페이스만 작성해도 CRUD를 할 수 있음

  •   public interface MemberRepository extends JpaRepository<Member, Long> {
        Member findByUsername(String username);
        // select m from Memer m where username =:username      
      }
          
    
  • 기본 제공 메소드
    • S : 엔티티 및 자식 타입, T : 엔티티, ID : 식별자
    • save(S) : 새로운 엔티티는 저장, 기존의 엔티티는 수정
    • delete(T) : 엔티티 삭제 (EntityManager.remove() 호출)
    • findById(ID) : 엔티티 하나를 조회 (EntityManager.find() 호출, Optional 반환)
    • getOne(ID) : 엔티티를 프록시로 조회 (EntityManager.getReference() 호출)
    • findAll(…) : 모든 엔티티를 조회, 정렬이나 페이징 조건을 파라미터로 지정 가능
  • 쿼리 메소드 기능
    • 메소드 선언(이름)만으로 JPQL 쿼리를 사용하는 구현체를 만들어주는 기능
    • 쿼리 메소드 기능은 크게 3가지
      • 메소드 이름으로 쿼리 생성
      • 메소드 이름으로 JPA NamedQuery 호출
      • @Query 어노테이션을 사용해서 리포지토리 인터페이스에 쿼리 직접 정의
  • 메소드 이름으로 쿼리 생성
    • 거의 사용 안함..
    • 이름과 이메일로 회원을 조회할 때?
    •   public interface MemberRepository extends JpaRepository<Member, Long> {
          Member findByEmailAndName(String email, String name);
        }
      
    •   select m from Member m where m.email=:email and m.name=:name
      
  • JPA NamedQuery
    • JPA의 NamedQuery를 메소드 이름으로 호출할 수 있음
    • 일단 아래와 같은 NamedQuery가 있다고 했을 때?
    • @Entity
      @NamedQuery(
        name="Member.findByUsername",
        query="select m from Member m where m.username = :username")
      public class Member {
        ...
      }
      
    • 이런 NamedQuery를 스프링 데이터 JPA를 이용해서 메소드 이름으로 호출이 가능함
    • public interface MemberRepository extends JpaRepository<Member, Long> {
        @Query(name="Member.findByUsername") // NamedQuery의 이름과 메소드 이름이 동일하면 생략해도 됨
        List<Member> findByUsername(@Param("username") String username);
      }
      
    • NamedQuery를 클래스에 어노테이션으로, 또는 xml로 빼야하는 번거러움이 있어 실무에서 잘 사용하지 않음
      • 유일한 장점?
        • 애플리케이션 로딩 시점에 sql을 파싱해서 문법 오류를 알려줌
  • @Query, 리포지토리 인터페이스에 쿼리 직접 정의
    • 스프링 데이터 JPA의 리포지토리 인터페이스에 직접 쿼리 정의가 가능
    • public interface MemberRepository extends JpaRepository<Member, Long> {
        @Query("select m from Member m where m.username = :username")
        List<Member> findByUserName(@Param("username") String username);
      }
      
  • 사용자 정의 리포지토리
    • 복잡한 쿼리를 사용해야 해서 메소드를 직접 구현해야 할 때?
      • 인터페이스의 구현체를 직접 만들면 스프링 데이터 JPA가 지원하는 메소드도 직접 구현을 해줘야 함
      • 내가 필요한 메소드만 직접 정의해서 사용하고 싶을때?
    • /* interface MemberRepositoryCustom */
      public interface MemberRepositoryCustom {
        public List<Member> findMemberCustom();
      }
      
    • /* class MemberRepositoryCustomImpl */
      public class MemberRepositoryImpl implements MemberRepositoryCustom {
        @Overrride
        public List<Member> findMemberCustom(){
          ...
        }
      }
      
    • /* interface MemberRepository */
      public interface MemberRepository implements JpaRepository<Member, Long>, MemberRepositoryCustom {
        ...
      }
      
    • 1





© 2020.02. by blupine