Spring Data JPA ?
spring framework에서 JPA를 편리하게 사용할 수 있도록 지원
- CRUD 처리를 위한 공통 인터페이스 제공
- repository 개발 시 인터페이스만 작성하면, 실행 시점에 spring data JPA가 구현 객체를 동적으로 생성해서 주입
- 데이터 접근 게청(repository) 구현 시 클래스 없이 인터페이스만 작성하여 개발을 완료하도록 지원
- 공통메소드는 spring data jpa가 제공하는 의존성 라이브러리에 포함되어 있음
사용하기 위해선
라이브러리를 의존성 추가해줘야 함 (build.gradle
)
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
JpaRepository
Spring Data Jpa 모듈
Repository
|
CrudRepository
|
...
|
JpaRepository
JpaRepository
인터페이스를 상속받으면 사용할 수 있는 주요 메서드
// em : EntityManager
save(S)
: 새로운 엔티티는 저장하고, 이미 있는 엔티티는 수정- 내부에서 식별자 값이 없으면 em.persist(), 있으면 em.merge() 호출
delete(T)
: 엔티티 하나 삭제- 내부에서 em.remove() 호출
findByOne(id)
: 엔티티 1개를 id 값으로 조회- 내부에서 em.find() 호출
getOne(id)
: 엔티티를 프록시로 조회- 내부에서 em.getReference() 호출
findAll()
: 모든엔티티 조회 (sort, pagable 조건을 파라미터로 제공)
쿼리메소드 기능
JpaRepository 인터페이스를 상속한 Repository 계층의 클래스에 메소드의 이름으로 적절한 JPQL 쿼리를 생성하여 실행
JPQL?
선언한 도메인 클래스 +.(점) + 메서드 이름으로 Named쿼리
ex. select a from Account a where a.name = ?1
- JPA가 제공하는 쿼리 메소드 기능
- 메소드 이름으로 쿼리 생성 가능
- JPA NamedQuery 호출
- @Query 어노테이션을 사용하여 쿼리 직접 정의 가능
Spring Data JPA 쿼리 생성
- 엔티티의 필드명 변경 시 인터페이스에 정의한 메소드명도 변경해주어야 함
- 이 작업이 제대로 되지 않으면 처음 앱 실행 시 bean이 찾지 못할 수도 있음
- 이 작업이 제대로 되지 않으면 처음 앱 실행 시 bean이 찾지 못할 수도 있음
ex.
@Repository
public interface PerformanceRepository extends JpaRepository<Performance, Long> {
//startDate보다 같거나 큰(<=) 모든 모든 값을 startDate를 기준으로 오름차순으로 정렬하여 조회
List<Performance> findByStartDateGreaterThanEqualOrderByStartDateAsc(Date startDate);
//title과 같으면서(and) startDate보다 같거나 큰(<=) 모든 모든 값을 startDate를 기준으로 오름차순으로 정렬하여 조회
List<Performance> findByTitleAndStartDateGreaterThanEqualOrderByStartDate(String title, Date startDate);
}
JPA NamedQuery 호출
메소드 이름으로 Jpa Named 쿼리 호출이 가능하다.
@Repository
public interface PerformanceRepository extends JpaRepository<Performance, Long> {
List<Performance> findByTitle(@Param("title") String title);
}
- 쿼리에 이름을 부여하여 사용
- 어노테이션이나 xml에 쿼리를 정의
어노테이션으로 정의
@Entity @NamedQuery( name = "Performance.findByTitle" query = "select p from Performance p where p.title = :title") public class Performance{ ... }
xml로 정의
<named-query name="Performance.findByTitle"> <query><CDATA[ select p from Performance p where p.title = :title ]/></query> </named-query>
직접 쿼리 정의
@Repository public interface PerformanceRepository extends JpaRepository<Performance, Long> { //1. 직접 쿼리 정의 @Query("select p from Performance p where p.title = :title") List<Performance> findByTitle(String title); //2. Native SQL 사용 @Query(value = "select m from Performance p where p.title = :title", nativeQuery = true) List<Performance> findByTitle(String title); }
원하는 값만 매핑하여 return 하고 싶을 경우, Mapping에 관한 인터페이스를 따로 정의하거나 DTO를 만들어서 Repository의 메소드의 return 타입을 해당 값으로 지정해줘야 함
ex.
public interface PerformanceMapping {
String getTitle();
Date getStartDate();
Date getEndDate();
String getPrice();
String getDescription();
String getRunningTime();
}
//이런 식으로 원하는 값만 매핑해서 return 하도록
List<PerformanceMapping > findByStartDateGreaterThanEqualOrderByStartDateAsc(Date startDate);
참고
'Development > Spring' 카테고리의 다른 글
redis 설치 및 redisson을 이용한 분산락 구현 (0) | 2021.10.09 |
---|---|
@RequestParam Date 타입 받기 (0) | 2021.09.25 |
Spring의 Transaction (0) | 2021.09.23 |
Spring? Spring Boot? Spring MVC? (0) | 2021.09.23 |
[JAVA 에러] java.lang.IllegalStateException: Ambiguous mapping found. (0) | 2021.09.23 |
댓글