Spring Data JPA

Ada·2022년 10월 8일
0

항해TOL

목록 보기
30/63

Spring Data JPA 란?

  • JPA 를 편리하게 사용하기 위해, 스프링에서 JPA 를 Wrapping
  • 스프링 개발자들이 JPA 를 사용할 때 필수적으로 생성해야 하나, 예상 가능하고 반복적인 코드들 → Spring Data JPA 가 대신 작성
  • Repository 인터페이스만 작성하면, 필요한 구현은 스프링이 대신 알아서 해줌

Spring Data JPA 예제

@Entity
public class Product extends Timestamped {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;
    private Long userId;
    private String title;
    private String image;
    private String link;
    private int lprice;
    private int myprice;
}
public interface ProductRepository extends JpaRepository<Product, Long> {
}
// 1. 상품 생성
Product product = new Product(...);
productRepository.save(product);

// 2. 상품 전체 조회
List<Product> products = productRepository.findAll();

// 3. 상품 전체 개수 조회
long count = productRepository.count();

// 4. 상품 삭제
productRepository.delete(product);
public interface ProductRepository extends JpaRepository<Product, Long> {
    // (1) 회원 ID 로 등록된 상품들 조회
    List<Product> findAllByUserId(Long userId);

    // (2) 상품명이 title 인 관심상품 1개 조회
		Product findByTitle(String title);

		// (3) 상품명에 word 가 포함된 모든 상품들 조회
		List<Product> findAllByTitleContaining(String word);

		// (4) 최저가가 fromPrice ~ toPrice 인 모든 상품들을 조회
    List<Product> findAllByLpriceBetween(int fromPrice, int toPrice);
}

ID 외의 필드에 대한 추가 기능은 interface 만 선언해 주면, 구현은 Spring Data JPA 가 대신 해준다.

JPA 추가기능 구현 방법은 공식문서에 명시되어있음.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods

쿼리 메소드 기능

인터페이스에 메소드만 선언하면 해당 메소드의 이름으로 적절한 JPQL 쿼리를 생성해서 실행


엔티티의 필드명이 변경되면 인터페이스에 정의한 메소드 이름도 꼭 함께 변경해주어야 한다.

@Query Annotaion을 사용해서 Repository interface에 쿼리 직접 정의

Repository 메소드에 직접 쿼리를 정의

  • @org.springframework.date.jpa.repository.Query Annotation 사용
  • 실행할 메소드에 정적 쿼리를 직접 작성 (이름 없는 Named 쿼리)
  • 애플리케이션 실행 시점에 문법 오류를 발견할 수 있는 장점

Native SQL을 사용할 경우

  • @Query Annotation에 nativeQuery=true 설정
  • 파라미터 바인딩이 0부터 시작

파라미터 바인딩

위치 기반 파라미터 바인딩

"select m from Member m where m.username = ?1"

이름 기반 파라미터 바인딩

"select m from Member m where m.username = :name"
  • 코드의 가독성과 유지보수를 위해 이름 기반 파라미터 바인딩을 권장

벌크성 수정 쿼리

@org.springframework.date.jpa.repository.Modifying

  • 벌크성 쿼리를 실행한 후 영속성 컨텍스트를 초기화하고 싶다면 @Modifying(clearAutomatically=true)

반환타입

결과가 한 건 이상이면 컬렉션 인터페이스 사용
List findByName(String name);

  • 조회 결과가 없다면 빈 컬렉션 반환

단건이면 반환 타입을 지정
Member findByEmail(String email);

  • 조회 결과가 없다면 null 반환
  • 결과가 2건 이상 조회되면 ..NonUniqueReulstException 예외 발생 (.getSingleResult() 메소드를 호출하므로)

페이징과 정렬

스프링 데이터 JPA는 쿼리 메소드에 페이징과 정렬 기능 제공

  • org.springframework.data.domain.Sort : 정렬 기능
  • org.springframework.data.domain.Pageable : 페이징 기능(내부에 Sort 포함)

ㅇ 파라미터에 Pageable을 사용하면 

  • 반환 타입으로 List나 org.springframework.data.domain.Pageable 사용 가능
  • 반환 타입으로 Page를 사용하면 스프링 데이터 JPA는 페이징 기능을 제공하기 위해
    검색된 전체 데이터 건수를 조회하는 count쿼리를 추가로 호출
// count 쿼리 사용
  Page<Member> findByName(String name, Pageable Pageable); 
  // count 쿼리 사용 X
  List<Mamber> findByName(String name, Pageable Pageable); 
  List<Mamber> findByName(String name, Sort sort);
profile
백엔드 프로그래머

0개의 댓글