[JPA]即時ロード(Eager)と遅延ロード(Lazy)
3137 ワード
Webプロジェクトの実行中に双方向マッピング関係におけるN+1の問題に遭遇した.
N+1問題の原因と解決策の前に,即時ロードと遅延ロードを理解すべきであると考えられる.
即時ロードと遅延ロードは、2つの双方向マッピングがあるEntityを指定し、1つのEntityをクエリーするときにマッピングされたEntityを同時にクエリーするか、実際のマッピングが必要なEntityクエリーをクエリーするときにクエリーするかを指定します.
ビジネスロジックでは、特定のエンティティに関連するロジックのみが使用され、マッピングされたエンティティにクエリーされると効率が低下します.この問題は、JPAがプロキシクエリを介して遅延ロードを使用して解決します.
次の例について詳しく説明します.
ユーザー、Post Entity、およびPost Entityを問い合わせるロジックがある場合、Post Entityのロード時にLazyロードに設定されたユーザーEntityがFreshオブジェクトにインポートされます. 以降、クエリは実際のオブジェクトを使用するときに実行されます. getUser()関数を使用してユーザーを問い合わせると、プロキシオブジェクトが問い合わされます. getUser().getXXX()関数を使用してユーザーフィールドにアクセスすると、クエリーが実行されます. ほとんどの論理で2つのEntityが同時に使用されている場合、Lazyを使用すると2回のselectクエリが実行されます.
これは、非常に遅いディスクに2回アクセスする必要があるため、非常に効率的ではありません.
この場合、「即時ロード」(Eager)を使用して2つのEntityを一緒にクエリーすることが有効です.は、プロキシオブジェクトではなく結合を使用してマッピングされたEntityを同時にクエリーするときにロードします. の場合は、すぐにロードを使用しないほうがいいです. がすぐにロードされると、JPQLにN+1の問題が発生します.(遅延ロードを使用するとN+1に問題が発生しないという意味ではありません...他の方法で解決する必要があります)
N+1問題については,次の位置決めを行う.
N+1問題の原因と解決策の前に,即時ロードと遅延ロードを理解すべきであると考えられる.
即時ロードと遅延ロード
即時ロードと遅延ロードは、2つの双方向マッピングがあるEntityを指定し、1つのEntityをクエリーするときにマッピングされたEntityを同時にクエリーするか、実際のマッピングが必要なEntityクエリーをクエリーするときにクエリーするかを指定します.
ビジネスロジックでは、特定のエンティティに関連するロジックのみが使用され、マッピングされたエンティティにクエリーされると効率が低下します.この問題は、JPAがプロキシクエリを介して遅延ロードを使用して解決します.
次の例について詳しく説明します.
ディレイロード
@Entity
@AllArgsConstructor
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private String password;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private List<Post> postList;
}
@Entity
@AllArgsConstructor
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
private String writer;
@ManyToOne(fetch = FetchType.LAZY)
private User user;
}
これは、非常に遅いディスクに2回アクセスする必要があるため、非常に効率的ではありません.
この場合、「即時ロード」(Eager)を使用して2つのEntityを一緒にクエリーすることが有効です.
即時ロード(Eager)
@Entity
@AllArgsConstructor
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private String password;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
private List<Post> postList;
}
@Entity
@AllArgsConstructor
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
private String writer;
@ManyToOne(fetch = FetchType.EAGER)
private User user;
}
遅延ロードとは異なり、N+1問題については,次の位置決めを行う.
Reference
この問題について([JPA]即時ロード(Eager)と遅延ロード(Lazy)), 我々は、より多くの情報をここで見つけました https://velog.io/@chjh121/JPA-즉시로딩Eager과-지연로딩Lazyテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol