2019. 6. 15. 03:19ㆍ[정리] 기능별 개념 정리/JPA
예시
@Data
@Entity("member")
public class MemberEntity{
@Id
@GeneratedValue
private long id;
private String name;
@OneToOne
@JoinColumn("country_id")
private CountryEntity country;
}
@Data
@Entity("country")
public class CountryEntity{
@Id
@GeneratedValue
private long id;
private String name;
}
public interface MemberRepository extends JpaRepository<MemberEntity, Long> {
List<MemberEntity> findByName(String name);
}
MemberEntity memberEntity = memberRepository.findByName("kok202").get();
맵핑 정보가 @ManyToOne, @OneToOne 일 경우 기본 Fetch 전략이 EAGER 이다.
EAGER 를 해오는 방식을 두가지로 생각해볼 수 있다.
방법 1. 조인을 해서 데이터를 한번에 가져온다.
방법 2. Fetch eager 인 데이터들을 대상으로 select 쿼리를 한번 더 날려서 가져온다.
JPA는 이전에는 방법 1을 이용하여 fetch eager 를 구현하였으나 방법 2로 변경되었다.
그래서 위 예시의 findByCountry 쿼리는 총 두개의 쿼리가 발생시킨다.
1. select * from member where member.name = 'kok202'
2. select * from country where country.id = ?
select 쿼리에 join 을 시켜서 데이터를 가져오게함으로서 select 쿼리의 발생을 줄이고 싶다면 @EntityGraph 를 사용할 수 있다.
public interface MemberRepository extends JpaRepository<MemberEntity, Long> {
@EntityGraph(attributePaths = "country")
List<MemberEntity> findByName(String name);
}
country 를 fetch eager 해올 때는 조인을 통해 가져온다.
위의 결과는 하나의 쿼리만 발생시킨다.
select * from member inner join country on country.id = member.country_id where member.name = 'kok202'
번외 EntityGraphType (기본값 : EntityGraphType.FETCH)
@EntityGraph(attributePaths = "country", type = EntityGraphType.FETCH)
@EntityGraph(attributePaths = "country", type = EntityGraphType.LOAD)
EntityGraphType.FETCH : attributePaths 정의한 멤버변수만 EAGER 로 불러오고 나머지는 LAZY 로 불러온다. 즉 멤버변수의 FetchType이 뭐였는지 신경쓰지 않는다. FetchType.EAGER 인 멤버변수가 있었어도 EntityGraph 의 attributePaths 에 정의되어있지 않다면 Lazy 로 불러오게 된다.
EntityGraphType.LOAD : attributePaths 정의한 멤버변수는 EAGER 로 불러오고 나머지 멤버변수는 각자의 FetchType을 존중해서 불러온다.
출처 : https://www.youtube.com/watch?v=Ec17RS8R7zc
'[정리] 기능별 개념 정리 > JPA' 카테고리의 다른 글
JPA : Query 발생 시점 (0) | 2019.06.17 |
---|---|
JPA : Embeddable (0) | 2019.06.17 |
JPA fetch 맵핑별 기본값 (0) | 2019.06.14 |
JPA delete (0) | 2019.06.12 |
Differences between @Entity(name) and @Table(name) (0) | 2019.05.20 |