[JPA]遅延ロードとインスタントロード(JPA基本編by金英漢)
遅延ロードとインスタントロード
遅延ロードとインスタントロードについては、以前によく知られていたエージェントの概念を思い出してみましょう.)
たとえば、チームとメンバーが1対以上の関連関係を持っている場合、メンバーのチームを表示するたびに表示しますか?これは、お客様のビジネスニーズに依存します.その必要がなければ、それは無駄でしょう.
この場合、遅延ロードが使用されます.実際には、チームに関する情報をメンバーで取得する必要がある前に、データベースはクエリーを遅らせます.🤗 (どこかでいろいろなコンセプトを聞いたことがありますが…)
したがって、メンバーをブラウズするときに、以下のようにエージェントオブジェクトをTeamオブジェクトに入れます.そしてgetTeamのように、実際にチームが必要な場合に初期化!
遅延ロードに設定するには、以下に示すようにfetchオプションを簡単にLAZYに設定します.
public class Member {
@ManyToOne(fetch = FetchType.LAZY) // 다대일(member관점) + 프록시객체로 조회
@JoinColumn(name= "TEAM_ID") // FK는 뭔지
private Team team;
}
もちろん、逆に(すぐにロードする必要がある場合:常にメンバーとチームを同時に表示する)、fetchオプションをEAGERに設定できます. @ManyToOne(fetch = FetchType.EAGER)
実際のコードを見て、クエリーがどのように行われているかを見てみましょう.Member member = new Member();
member.setUsername("a");
Team team = new Team();
team.setName("b");
member.setTeam(team);
em.persist(member);
em.persist(team);
em.flush();
em.clear();
Member findMember = em.find(Member.class, member.getId());
System.out.println("member = " + findMember.getClass()); // 멤버객체
System.out.println("team = " + findMember.getTeam().getClass()); // 프록시객체
System.out.println("team = " + findMember.getTeam().getName()); // 초기화하면서 select문날림
即時ロード(EAGER)
JPAは最適化されるので、joinを使用してチームをインポートします.
select
.....
from
Member member0_
left outer join
Team team2_
on member0_.TEAM_ID=team2_.TEAM_ID
where
member0_.MEMBER_ID=?
遅延ロード(LAZY)
遅延ロード時にjoinは行わないことに注意してください.
select
.....
from
Member member0_
where
member0_.MEMBER_ID=?
もちろん、JPAの最適化によって大きな違いがあるかもしれませんが、JPQLを使うともっと違いがあります.JPQL
JQCLのメンバーを使用するには、クエリー全体でメンバーをクエリーします.
Member member = new Member();
member.setUsername("a");
Team team = new Team();
team.setName("b");
member.setTeam(team);
em.persist(member);
em.persist(team);
em.flush();
em.clear();
List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
System.out.println(members);
即時ロード(EAGER)
JPQLは、渡されたクエリーに従って作成されるため、JPAは最適化されません.したがって、メンバーにselect文が1回送信され、メンバーチームの値(クエリー全体に使用)が取得されます.select文は1回、合計2回、すぐにロードされます.
今はメンバーが少ないけど...メンバーが多く、他のチームに属している場合は、N+1の問題が発生する可能性があります.N+1問題は、メンバーの完全なクエリー時に発行されたクエリー(select*fromメンバーm)による他のNクエリー(各メンバーのチームにselect文がある)である.
Hibernate:
select
....
from
Member member0_
Hibernate:
select
team0_.TEAM_ID as team_id1_7_0_,
team0_.name as name2_7_0_
from
Team team0_
where
team0_.TEAM_ID=?
遅延ロード(LAZY)
遅延ロードの場合、クエリーは1回のみ実行されます.
Hibernate:
select
....
from
Member member0_
🔥n/a.結論🔥できるだけすべての関連関係の遅延ロードをdefaultに設定し、本当に必要なときにすぐにロードに変更します.
Reference
この問題について([JPA]遅延ロードとインスタントロード(JPA基本編by金英漢)), 我々は、より多くの情報をここで見つけました https://velog.io/@rmswjdtn/JPA-지연로딩과-즉시로딩-JPA-기본편-by-김영한テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol