스프링 데이터 JPA
스프링 데이터 JPA 주요 기능
- 스프링 데이터 JPA : JPA를 편리하게 사용할 수 있도록 도와주는 라이브러리이다.
- 스프링 데이터 JPA가 제공하는 기능 : 공통 인터페이스 기능, 쿼리 메소드 기능을 제공한다.
- 공통 인터페이스 기능 : JpaRepository 인터페이스로 기본적인 CRUD 기능 제공
- 쿼리 메소드 기능 : 인터페이스에 메소드만 적어두면 메소드 이름을 분석해서 쿼리를 자동으로 만들고 실행해준다.
public interface ItemRepsitory extends JpaRepository <Item, Long> {
}
- 공통 인터페이스 기능 JpaRepsoitory 사용법
- JpaRepository 인터페이스를 상속받는 인터페이스를 선언
- 제네릭 타입에 <엔티티, 엔티티ID>를 선언
- JpaRepository를 상속받으면 JpaRepository가 제공하는 기본 CRUD를 모두 사용할 수 있다.
- 스프링 데이터 JPA가 프록시 기술을 사용해서 인터페이스의 구현 클래스를 만들어주며 구현 클래스의 인스턴스를 만들어서 스프링 빈으로 등록해준다.
- JpaRepository를 상속받는 인터페이스만 만들면 구현 클래스 없이 기본 CRUD 기능을 사용할 수 있다.
//순수 JPA 레포지토리
public List<Member> findByUsernameAndAgeGreaterThan(String username, int age) {
return em.createQuery("select m from Member m where m.username = :username and m.age > :age")
.setParameter("username", username)
.setParameter("age", age) .getResultList();
}
//스프링 데이터 JPA
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}
//스프링 데이터 JPA JPQL 직접 사용
public interface SpringDataJpaItemRepository extends JpaRepository<Item, Long> {
//쿼리 메서드 기능
List<Item> findByItemNameLike(String itemName);
//쿼리 직접 실행
@Query("select i from Item i where i.itemName like :itemName and i.price <= :price")
List<Item> findItems(@Param("itemName") String itemName, @Param("price") Integer price);
}
- 순수 JPA 레포지토리와 스프링 데이터 JPA 예제
- 순수 JPA 레포지토리 - 직접 JPQL 작성, 직접 파라미터 바인딩해줘야 한다.
- 스프링 데이터 JPA - 메소드 이름을 분석해서 필요한 JPQL을 자동으로 만들고 실행한다.
- 스프링 데이터 JPA가 제공하는 쿼리 메소드 기능을 사용하려면 규칙에 맞게 이름을 지어야 한다.
- JPQL은 JPA가 SQL로 번역해서 실행한다.
- JPQL을 직접 사용하는 경우 @Query와 함께 작성하면 되며 이때 메소드 이름으로 실행하는 규칙은 무시된다.
- JPA 네이티브 쿼리 기능도 지원하며 JPQL 대신 SQL을 직접 작성할 수 있다.
- 쿼리 메소드 기능 사용을 위한 명명규칙
- 조회 : find...By, read...By, query...By, get...By
- ex) findMemberBy와 같이 ...에 식별하기 위한 내용 / 설명이 들어가도 된다.
- By 이후에는 조건이 오며 And, Or로 표현할 수 있다.
- COUNT : count...By 반환타입 long
- EXISTS : exists...By 반환타입 boolean
- 삭제 : delete...By, remove...By 반환타입 long
- DISTINCT : findDistinct, findMemberDistinctBy
- LIMIT : findFirst3, findFirst, findTop, findTop3
- 주로 limit은 이렇게 사용하지 않고 파라미터를 통해 넘겨주는 형태로 사용한다.
- 조회 : find...By, read...By, query...By, get...By
스프링 데이터 JPA 적용
public interface SpringDataJpaItemRepository extends JpaRepository<Item, Long> {
List<Item> findByItemNameLike(String itemName);
List<Item> findByPriceLessThanEqual(Integer price);
//쿼리 메소드 (아래 메소드와 같은 기능 수행)
List<Item> findByItemNameLikeAndPriceLessThanEqual(String itemName, Integer price);
//쿼리 직접 실행
@Query("select i from Item i where i.itemName like :itemName and i.price <= :price")
List<Item> findItems(@Param("itemName") String itemName, @Param("price") Integer price);
}
- 스프링 데이터 JPA 예제 코드
- 스프링 데이터 JPA가 제공하는 JpaRepository 인터페이스를 상속받으면 기본적인 CRUD를 사용할 수 있다.
- 이름으로 검색, 가격으로 검색하는 등의 기능은 공통으로 제공할 수 있는 기능이 아니다.
- 공통으로 제공하는 기능이 아닌 경우 쿼리 메소드 기능을 사용하거나 @Query로 직접 쿼리를 작성해야 한다.
- 쿼리를 직접 실행하는 경우에 @Query 어노테이션 사용
- 쿼리 메소드 기능을 사용할 때는 파라미터를 순서대로 입력하면 되지만 @Query로 직접 쿼리를 실행할 때는 파라미터를 명시적으로 바인딩해야 한다.
- 파라미터 바인딩은 @Param("파라미터명") 어노테이션 사용
- 해당 예제에서는 조건 4가지로 분류해서 데이터를 검색
- 모든 데이터 조회 findAll() => JpaRepository를 통해 공통으로 제공하는 기능
- JPQL : select i from Item i
- 이름 조회 findByItemNameLike() => 쿼리 메소드 기능을 사용
- JPQL : select i from Item i where i.name like ?
- 가격 조회 findByPriceLessThanEqual() => 쿼리 메소드 기능을 사용
- JPQL : select i from Item i where i.price <= ?
- 이름 + 가격 조회 findByItemNameLikeAndPriceLessThanEqual() => 쿼리 메소드 기능 사용
findItems() => @Query로 직접 쿼리 작성- JPQL : select i from Item i where i.name like ? and i.price <= ?
- 모든 데이터 조회 findAll() => JpaRepository를 통해 공통으로 제공하는 기능
- 스프링 데이터 JPA가 제공하는 JpaRepository 인터페이스를 상속받으면 기본적인 CRUD를 사용할 수 있다.
- 쿼리 메소드 기능의 단점
- 조건이 많아지면 메소드 이름이 너무 길어진다.
- 조인 같은 복잡한 조건을 사용할 수 없다.
- 쿼리 메소드 기능은 간단한 경우에는 유용하지만 복잡한 경우 직접 JPQL을 작성하는 것이 좋다.
- 스프링 데이터 JPA도 동적 쿼리에 약하기에 Querydsl을 사용하면 편하다.
- 스프링 데이터 JPA에서도 동적 쿼리를 위해 Example이라는 기능을 제공한다.
- 기존 예제 구조
- ItemService 는 ItemRepository 에 의존하기 있기에 ItemService에서 SpringDataJpaItemRepository 를 그대로 사용할 수 없다.
- ItemService가 SpringDataJpaItemRepository에 의존하도록 코드를 직접 고칠 수 있지만 코드 변경없이 의존을 유지하면서 DI를 통해 구현 기술을 변경하기 위함
- JpaItemRepositoryV2라는 어댑터 역할의 클래스를 생성
- V2는 ItemRepository의 구현체이며 내부에서는 SpringDataJpaItemRepository에 의존하고 있다.
- ItemService 는 ItemRepository 에 의존하기 있기에 ItemService에서 SpringDataJpaItemRepository 를 그대로 사용할 수 없다.
- 스프링 데이터 JPA에서도 스프링 예외 추상화를 지원한다.
- @Repository가 없어도 예외 변환이 된다.
정리
- 스프링 데이터 JPA가 제공하는 기능 : 공통 인터페이스 기능, 쿼리 메소드 기능을 제공한다.
- 공통 인터페이스 기능 JpaRepsoitory 사용법
- JpaRepository 인터페이스를 상속받는 인터페이스를 선언
- 제네릭 타입에 <엔티티, 엔티티ID>를 선언
- JpaRepository를 상속받는 인터페이스만 만들면 구현 클래스 없이 기본 CRUD 기능을 사용할 수 있다.
- 스프링 데이터 JPA가 프록시 기술을 사용해서 인터페이스의 구현 클래스를 만들어주며 구현 클래스의 인스턴스를 만들어서 스프링 빈으로 등록해준다.
- 쿼리 메소드 기능
- 메소드 이름을 분석해서 필요한 JPQL을 자동으로 만들고 실행하며 메소드 명은 명명규칙에 맞게 작성해야 한다.
- JPQL은 JPA가 SQL로 번역해서 실행한다.
- JPQL을 직접 사용하는 경우 @Query와 함께 작성하면 되며 이때 메소드 이름으로 실행하는 규칙은 무시된다.
- 조건이 많아지면 메소드명이 길어지므로 직접 JPQL을 사용하는 것이 좋다.
- @Query로 직접 쿼리를 실행할 때는 파라미터를 명시적으로 바인딩해야 하며 파라미터 바인딩은 @Param("파라미터명") 어노테이션 사용
- JPA 네이티브 쿼리 기능도 지원하며 JPQL 대신 SQL을 직접 작성할 수 있다.
- 스프링 데이터 JPA도 스프링 예외 추상화를 지원한다.
출처 : [인프런 김영한 스프링 DB 2편 - 데이터 접근 활용 기술]
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-2/dashboard
스프링 DB 2편 - 데이터 접근 활용 기술 강의 | 김영한 - 인프런
김영한 | 백엔드 개발에 필요한 DB 데이터 접근 기술을 활용하고, 완성할 수 있습니다. 스프링 DB 접근 기술의 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 백엔드
www.inflearn.com
'Spring > [인프런 김영한 스프링 DB 2편 - 데이터 접근 활용 기술]' 카테고리의 다른 글
[인프런 김영한 스프링 DB 2편 - 데이터 접근 활용 기술] 데이터 접근 기술 - 활용 방안 (2) | 2024.11.27 |
---|---|
[인프런 김영한 스프링 DB 2편 - 데이터 접근 활용 기술] 데이터 접근 기술 - Querydsl (0) | 2024.11.26 |
[인프런 김영한 스프링 DB 2편 - 데이터 접근 활용 기술] 데이터 접근 기술 - JPA (1) | 2024.11.23 |
[인프런 김영한 스프링 DB 2편 - 데이터 접근 활용 기술] 데이터 접근 기술 - MyBatis (1) | 2024.11.21 |
[인프런 김영한 스프링 DB 2편 - 데이터 접근 활용 기술] 데이터 접근 기술 - 테스트 (1) | 2024.11.21 |