일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- springbootproxy
- gitinitial
- OSIV
- 제이피큐엘쿼리
- 이해와 원리
- spring
- JPAproxy
- 데이터베이트h2
- JPA프록시
- httppie
- springbootH2
- Git
- JPA Hint & Lock
- 에이치투데이터베이스
- 자바제너릭
- JPAmapping
- embededtype
- JDBC connection pool
- jpqlquery
- Open EntityManager
- MySqlType
- JPA값타입
- jpa
- javageneric
- sql
- 임베디드타입
- 스프링부트기본설정
- 스프링부트
- springboot기본설정
- dockercmd
Archives
- Today
- Total
빡코
[스프링 데이터 JPA] fetchJoin과 EntityGrap 본문
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/
Member와 Team은 N:1 지연로딩 관계이다. Team의 데이터를 조회할 때 마다 N+1의 쿼리 성능 문제가 발생한다.
public class Member {
@Id @GeneratedValue
@Column(name="member_id")
private Long id;
private String username;
private int age;
//가짜 객체를 먼저 가져온다.
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
}
@Test
public void findMemberLazy(){
//given
//member1 -> teamA
//member2 -> teamb
Team teamA = new Team("teamA");
Team teamB = new Team("teamB");
teamRepository.save(teamA);
teamRepository.save(teamB);
Member member1 = new Member("member1", 10, teamA);
Member member2 = new Member("member2", 20, teamB);
memberRepository.save(member1);
memberRepository.save(member2);
em.flush();
em.clear();
//when
List<Member> members = memberRepository.findAll();
for (Member member : members) {
System.out.println("member = " + member.getUsername());
System.out.println("member = " + member.getTeam().getName()); ---> 여기서 문제가 발생
}
}
JPQL 페치조인(실무사용)
Fetch 조인으로 연관 데이터 한번에 조회하기. 빈 proxy가 아닌 실제 조회된 데이터로 entityr가 채워진다.
public interface MemberRepository extends JpaRepository<Member, Long> {
@Query("select m from Member m left join fetch m.team") //member와 연관된 team을 한번에 끍어 온다.
List<Member> findMemberFetchJoin();
}
//실행 쿼리
select
member0_.member_id as member_i1_0_0_,
team1_.team_id as team_id1_1_1_,
member0_.age as age2_0_0_,
member0_.team_id as team_id4_0_0_,
member0_.username as username3_0_0_,
team1_.name as name2_1_1_
from
member member0_
left outer join
team team1_
on member0_.team_id=team1_.team_id
EntityGraph
-fetch 조인을 편리하게 할 수 있음.
//공통메서드오버라이드
@Override
@EntityGraph(attributePaths ={"team"})
List<Member>findAll();
@EntityGraph(attributePaths = {"team"})
@Query("select m from Member m")
List<Member> findMemberEntityGraph();
@EntityGraph(attributePaths = {"team"})
List<Member> findByUserName(@Param("username") String username);
NamedEntityGraph 사용방법
//Member
@NamedEntityGraph(name = "Member.all", attributeNodes = @NamedAttributeNode("team"))
public class Member {
}
//스프링 데이터 JPA 레포지토리
public interface MemberRepository extends JpaRepository<Member, Long> {
//@EntityGraph(attributePaths = {"team"})
@EntityGraph("Member.all")
List<Member> findEntityGraphByUsername(@Param("username") String username);
}
'Java > JPA' 카테고리의 다른 글
[스프링 데이터 JPA] 사용자 정의 리포지토리 구현 (0) | 2023.05.11 |
---|---|
[스프링 데이터 JPA] JPA Hint & Lock (0) | 2023.05.11 |
[스프링 데이터 JPA] 벌크성 수정 쿼리 (0) | 2023.05.11 |
[스프링 데이터 JPA] 예제 도메인, 공통인터페이스?, 쿼리 메서드, 반화타입 (0) | 2023.05.10 |
[스프링 데이터 JPA] 기초 설정 (0) | 2023.05.10 |