-
SpringDataJPA (1) - 공용 인터페이스, @QueryWeb/JPA 2024. 1. 30. 15:18
1. 공용 인터페이스 설정
- JavaConfig 설정 (부트 사용시 생략 가능)
@Configuration @EnableJpaRepositories(basePackages = "jpabook.jpashop.repository") public class AppConfig {}
- 스프링 부트 사용시 @SpringBootApplication 위치를 지정
- 만약 위치가 달라지면 @EnableJpaRepositories필요
- org.springframework.data.repository.Repository를 구현 클래스는 스캔 대상이 된다.
- 프록시로 동작한다.
- @Repository 어노테이션은 JPA 예외를 스프링 예외로 변환하는 과정을 처리한다.
- 컴포넌트 스캔을 스프링 데이터 JPA가 자동으로 처리 (인터페이스에 생략가능)
public interface MemberRepository extends JpaRepository<Member, Long> { } //JpaRepositroy인터페이스를 상속하고, 타입으로 엔티티 클래스와 기본 키 타입 넣음
- 대부분의 간단한 메서드는 이미 내부적으로 구현되어 있다.
2. 공용 인터페이스 분석
- JpaRepositroy 인터페이스 : 공통 CRUD 제공
- 제네릭은 <엔티티 타입, 식별자 타입> 설정
- T findOne(ID) -> Optional<T> findById(ID)로 변경
- boolean exists(ID) -> boolean existsById(ID)로 변경
제네릭 타입 : T (엔티티), ID(엔티티의 식별자 타입), S(엔티티와 그 자식타입)
- 주요메서드:
save : 새로운 엔티티는 저장하고 이미 있는 엔티티 병합
delete : 엔티티 하나 삭제 (내부에서 em.remove 호출)
findbyID : 엔티티 하나 조회 (em.find)
getOne : 엔티티를 프록시로 조회 (em.getReference() 호출)
findAll : 모든 엔티티 조회, 정렬이나 페이징 조건을 파라미터로 제공 가능
3. 쿼리 메소드 기능
3.1 메소드 이름으로 쿼리 생성
- 메소드 이름을 분석해서 JPQL 쿼리 생성함
List<Member> findByUsernameAndAgeGreaterThan(String username, int age)
> 조회 : find...By, read...By, query...By, get...By
...에는 메소드 식별을 위한 내용이 들어가도 된다. (findHello)
> COUNT: count...By 반환타입 long
> EXISTS: exists...BY 반환타입 boolean
> 삭제 : delete...By, remove...By 반환타입 long
> DISTINCT: findDistinct, findMemberDistinctBy
> LIMIT : findFrist3, findFirst,findTop,findTop3
-> 더 많은 규칙은 jpa공식문서를 찾아보자
* 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야한다. 그렇지 않으면, 애플리케이션 시작 시잠에 오류발생 (이거 장점이다!)
3.2 JPA NamedQuery 기능
- 잘 사용하지 않는다. 필요시 찾아보자
3.3 @Query
- 리포지토리 메소드에 쿼리를 정의하는 방법이다.
public interface MemberRepository extends JpaRepository<Member, Long> { @Query("select m from Member m where m.username = :username and m.age = :age") List<Member> findUser(@Param("username") String username, @Param("age") int age); }
- @org.springframwork.data.jpa.repository.Query 어노테이션을 사용
- 실행할 메서드에 정적 쿼리를 직접 작성하므로 이름 없는 Named 쿼리라 할 수 있음
- JPA Named 쿼리처럼 애플리케이션 실행 시점에 문법 오류 발견할 수 있음 > 매우 큰 장점
-> @Query 값 DTO 조회하기
단순히 값 하나를 조회
@Query("select m.username from Member m") List<String> findUsernameList(); //JPA 임베디드 타입도 이 방식으로 조회 가능 @Query("select new study.datajpa.dto.MemberDto(m.id,m.usrname,t.name) from Member m join m.team t") List<MemberDto> findMemberDto();
-> 파라미터 바인딩
- 이름 기반만 사용하자!
@Query("select m from Member m where m.username = :name") Member findMembers(@Param("name") String username)
- >컬렉션 파라미터 바인딩
@Query("select m from Member m where m.username in :names") List<Member> findByNames(@Param("names") List<String> names);
- > 반환 타입 (jpa는 유연한 반환 타입 지원)
List<Member> findByUsername(String name) Member findByUsername(String name) Optional<Member> findByUsername(String name)
-> 조회 결과가 많거나 없으면?
컬렉션 : 빈 컬렉션 반환
단건조회: null반환 (2건이상 반환시 예외발생)
'Web > JPA' 카테고리의 다른 글
JPA(2) - OSIV (0) 2024.01.22 JPA (2) - API 개발 시 기본으로 지켜야 할 사항 (0) 2024.01.22 JPA (11) - 다형성 쿼리,엔티티 직접 사용,정적쿼리,벌크연산 (0) 2024.01.12 JPA - 프로젝트 생성 (0) 2024.01.11 JPA 활용 (1-3) - 엔티티 설계시 주의점 (0) 2024.01.04