[JPA]即時ローディング(EAGER)と遅延ローディング(LAZY)(LAZYローディングと書くのはなぜですか?)(1)


前の記事ではProxyについて議論しました.
Proxyはこの記事のトピックのインスタントロードと遅延ロードを実現する重要な概念であり、まず、インスタントロードと遅延ロードとは何かを理解します.

上記の状況を考慮して、エンティティを作成しましょう.
@Entity
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @Column(name = "USERNAME")
    private String username;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}
@Entity
public class Team {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;

    private String name;

    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();
}
Entityは上と同じように簡単ですチームとメンバーは双方向の関連関係であり,関連関係のオーナーはメンバーである.△なぜ関連関係の主人がメンバーなのか理解できない場合は...関連関係の文章からもう一度読むことをお勧めします.😂)
注意すべき点は'fetch=FetchTypeEAGERの部分です以前にJPAで使用したことのない属性を説明していましたが、FetchTypeはEAGERに設定されています.(注意,@ManyToOneマッピングのデフォルトfetchはEAGERであり,省略してもEAGERとして動作する.
🎈 サンプルコード
Team team = new Team();
team.setName("teamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
em.persist(member);

em.flush();
em.clear();

Member findMember = em.find(Member.class, member.getId());
これは簡単なサンプルコードです.チームオブジェクトとメンバーオブジェクトを別々に作成し、メンバーオブジェクトのSetterメソッドでチームオブジェクトを設定し、em.find()メソッドでメンバーをクエリーします.
ここで重要なのは、メンバーをクエリーしたことに違いない.結果ログを見てみましょう.
🎉 ログ(EAGER時)
Hibernate: 
    select
        member0_.MEMBER_ID as MEMBER_I1_0_0_,
        member0_.TEAM_ID as TEAM_ID3_0_0_,
        member0_.USERNAME as USERNAME2_0_0_,
        team1_.TEAM_ID as TEAM_ID1_1_1_,
        team1_.name as name2_1_1_ 
    from
        Member member0_ 
    left outer join
        Team team1_ 
            on member0_.TEAM_ID=team1_.TEAM_ID 
    where
        member0_.MEMBER_ID=?
ちょっとおかしいです.メンバーを調べたのになぜチームにも入ったのか?
この魔法はfetch=FetchTypeです.これはEAGERの結果です.
では、fetchをLAZYに置き換えて実行します(fetch=FetchType.LAZY)
🎉 ログ(LAZY時)
Hibernate: 
    select
        member0_.MEMBER_ID as MEMBER_I1_0_0_,
        member0_.TEAM_ID as TEAM_ID3_0_0_,
        member0_.USERNAME as USERNAME2_0_0_ 
    from
        Member member0_ 
    where
        member0_.MEMBER_ID=?
今回はメンバーのクリック率しか見れませんでした
次に、メンバー・オブジェクトから実際にTeamオブジェクトのデータを要求するコードに遭遇した場合は、次の操作を行います.
findMember.getTeam().getName();		// 코드 자체엔 큰 의미가 없음, team 객체의 데이터를 요구하기 위한 코드
🎉 ログ(LAZY時)
Hibernate: 
    select
        team0_.TEAM_ID as TEAM_ID1_1_0_,
        team0_.name as name2_1_0_ 
    from
        Team team0_ 
    where
        team0_.TEAM_ID=?
チームデータを照会する照会文が表示されます…!
EAGERとLAZYの差はちょっと大きいかな?
EAGERは事前の意味での熱心な人で、熱心なようにメンバーを問い合わせると、関連関係のチームも一緒に問い合わせるが、LAZYは怠け者でメンバーのみを問い合わせるが、関連関係の他のデータは問い合わせるのを遅らせる.
一見、EAGERの方が良く見えます.
では、EAGERまたはLAZYロードを使用するのはどのような場合ですか?
まず理論的に以下のように説明する.
ビジネスロジックでメンバーデータが必要な場所でもTeamのほとんどのデータを同時に使用する必要がある場合はどうなりますか?FetchTypeをEAGERに設定し、常にチームとメンバーをクエリーすることをお勧めします.
ほとんどのメンバーを使用する場所でTeamデータが必要ない場合は?FetchTypeをLAZYに設定し、メンバーのみを表示し、チームを必要としない場合は、チームへのクエリーを再度送信することをお勧めします.
🔑
しかし、上述したように、この部分は極めて理論的な説明であり、実際の作業ではEAGER LOADINGを使用しないことを提案している.次の文章では、なぜLAZY LOADINGを使うのか、EAGER LOADINGがどのような問題を起こすのかを正式に理解してみましょう.