-
Notifications
You must be signed in to change notification settings - Fork 4
Description
무μμ μκ² λμλμ?
νλ‘μ κ°μ²΄ (Proxy Object)
λ¨Όμ νλ‘μ κ°μ²΄μ λν κ°λ λΆν° κ°λ¨ν μ΄ν΄λ΄ μλ€.
νλ‘μ κ°μ²΄λ μν°ν°μ μ€μ λ°μ΄ν°λ₯Ό λ°μ΄ν°λ² μ΄μ€μμ κ°μ Έμ€λ μμ μ μ§μ°μν€κΈ° μν΄ μλ³Έ(νκ²) κ°μ²΄λ₯Ό λμ ν΄μ νΈμΆλ κ°μ§ κ°μ²΄μ΄λ€.
νλ‘μ κ°μ²΄λ ν΄λΌμ΄μΈνΈ μ½λμ μ€μ λ°μ΄ν°λ² μ΄μ€μμ λ‘λλ μν°ν° κ°μ²΄(νκ² κ°μ²΄) μ¬μ΄μ μμΉνκΈ° λλ¬Έμ ν΄λΌμ΄μΈνΈλ μ€μ μν°ν° κ°μ²΄μ μ§μ μ κ·Όνμ§ μκ³ , νλ‘μ κ°μ²΄λ₯Ό ν΅ν΄ κ°μ μ μΌλ‘ μ κ·Όνκ² λ©λλ€.
μ½κ² λΉμ νμλ©΄ νκ² κ°μ²΄λ₯Ό μ§ μ£ΌμΈμ΄λΌκ³ μκ°νμ λ, νλ‘μ κ°μ²΄λ μ§ μ£ΌμΈμ λμ ν΄μ κ³μ½μ μμ²λ°λ μ€κ°μΈμΌλ‘ μκ°νλ©΄ λκ² λ€μ!
μ§μ° λ‘λ© (Lazy Loading)
μ§μ° λ‘λ©μ μν°ν°κ° λ‘λλ λ, μ°κ΄λ μν°ν°λ₯Ό μ¦μ λ‘λνμ§ μκ³ νμν μμ μ μ°κ΄λ κ°μ²΄μ λ°μ΄ν°λ₯Ό λ‘λνλ λ°©μμ
λλ€. @OneToMany λ @ManyToMany λ κΈ°λ³Έ μ€μ μ΄ μ§μ°λ‘λ©μ΄λΌκ³ ν©λλ€:D
@ManyToOne(fetch = FetchType.LAZY) // μ§μ° λ‘λ© μ€μ λ°©λ²μ°κ΄κ΄κ³λ₯Ό λ§Ίμ μν°ν° μ΄λ μ¬μ©λλ κ²μ΄ λ°λ‘ νλ‘μ κ°μ²΄μΈλ°μ, μ§μ° λ‘λ© λ°©μμμλ μ°κ΄λ μν°ν° λ°μ΄ν°λ μ€μ λ‘ μ κ·Όν λκΉμ§ λ‘λλμ§ μμ΅λλ€. μ¦, ν΄λΌμ΄μΈνΈ μ½λκ° κ°μ²΄μ λ©μλλ₯Ό νΈμΆν΄μΌ λΉλ‘μ νλ‘μ κ°μ²΄λ κ·Έ μκ° λ°μ΄ν°λ² μ΄μ€μ μ κ·Όνμ¬ μ€μ λ°μ΄ν°λ₯Ό λ‘λνκ² λ©λλ€.
μ½λλ‘ νλ² μ΄ν΄λ΄ μλ€!
public Blog getBlogByPostId(Long postId) {
Post post = postRepository.findById(postId).orElseThrow(() -> new NotFoundException("Post not found"));
Blog blog = post.getBlog();
return blog;
}Post μν°ν° λ΄μμ Blogμ λν μ κ·Όμ FetchType.LAZY μ¦, μ§μ° λ‘λ©μΌλ‘ μ€μ λμ΄ μκΈ° λλ¬Έμ Post κ°μ²΄λ§ λ¨Όμ λ‘λλκ³ Blogμ λν νλ‘μ κ°μ²΄κ° μμ±λκ² λ©λλ€. κ·Έ ν, getter ν¨μλ₯Ό ν΅ν΄ post.getBlog() λ₯Ό νΈμΆνλ©΄, νλ‘μ κ°μ²΄λ μ€μ λ°μ΄ν°κ° νμν μμ μ΄κΈ° λλ¬Έμ λΉλ‘μ λ°μ΄ν°λ² μ΄μ€μ μ κ·Όνμ¬ Blog λ°μ΄ν°λ₯Ό λ‘λνκ² λλ κ²μ΄μ£ !
μ¦μ λ‘λ© (Eager Loading)
μ¦μ λ‘λ©μ΄λ λ§ κ·Έλλ‘ λ°μ΄ν°λ₯Ό μ‘°νν λ, μ°κ΄λ λͺ¨λ κ°μ²΄μ λ°μ΄ν°κΉμ§ ν λ²μ λΆλ¬μ€λ λ°©μμ
λλ€. @ManyToOne λ @OneToOne λ κΈ°λ³Έ μ€μ μ΄ μ¦μ λ‘λ©μ΄λΌκ³ νλ€μ:D
@OneToMany(fetch = FetchType.EAGER) // μ¦μ λ‘λ© μ€μ λ°©λ²μμ μ½λλ‘ νλ² μ΄ν΄λ΄ μλ€.
μκΉμ μ½λμμ λ§μ½ Post μν°ν°μ Blog μν°ν°κ° FetchType.EAGER μ¦, μ¦μ λ‘λ©μΌλ‘ μ€μ λμ΄ μλ€λ©΄ μ΄λ»κ² λ κΉμ? postRepository.findById(postId) λ©μλλ₯Ό ν΅ν΄ Post μν°ν°λ₯Ό μ‘°νν λ μ¦μ Post λ°μ΄ν°μ μ°κ΄λ Blog λ°μ΄ν°κ° ν¨κ» λ‘λλ©λλ€. νλ‘μ κ°μ²΄μ μμ± μμ΄ λ³λμ 쿼리λ₯Ό ν΅ν΄ λ°λ‘ Blog μν°ν°μ μ κ·Όνλ κ²μ΄μ£ !
μ΄μ²λΌ μ¦μ λ‘λ© λ°©μμ μ§μ° λ‘λ© λ°©μμ λΉν΄ μ°κ΄λ λ°μ΄ν°κ° νμν μμ μμ λΉ λ₯΄κ² μ²λ¦¬λ₯Ό ν μ μλ€λ μ₯μ μ΄ μκ² λ€μ! νμ§λ§!!! νΉν μ€λ¬΄μμλ μ¦μ λ‘λ©μ κ°κΈμ μ¬μ©νμ§ μλλ€κ³ ν©λλ€! μ΄ μ΄μ λ‘λ μμΌλ‘ μ€λͺ ν JPA N+1 λ¬Έμ μλ μ°κ΄μ΄ μμ΅λλ€.
JPA N+1 λ¬Έμ
JPA N+1 λ¬Έμ λ?
JPA N+1 λ¬Έμ λ λ°μ΄ν°λ₯Ό μ‘°νν λ, 1κ°μ μΏΌλ¦¬λ‘ μμ²μ΄ μ²λ¦¬ν κ²μΌλ‘ κΈ°λνμΌλ μλνμ§ μμ Nκ°μ μΏΌλ¦¬κ° μΆκ°μ μΌλ‘ λ λ°μνλ νμμ λ§ν©λλ€.
λ§λ‘λ§ λ€μΌλ λ무 λͺ¨νΈν κ² κ°λ€μ. μ΄ μμ μ½λλ₯Ό νλ² μ΄ν΄λ΄ μλ€
public void getAllBlogTitleByPostId(Long postId) {
List<Post> posts = postRepository.findByPostId(postId);
for (Post post : posts) {
System.out.println(post.getBlog().getTitle());
}
}ν΄λΉ λ©μλλ₯Ό μ€νμν€λ©΄ λ€μ μμμ λ°λΌ μΏΌλ¦¬λ¬Έμ΄ λ°μνκ² μ£ !
- μ£Όμ΄μ§ postIdμ λμνλ λͺ¨λ Post κ°μ²΄λ€μ λ°μ΄ν°λ² μ΄μ€λ‘λΆν° λ‘λνλ 쿼리λ₯Ό λ°μμν¨λ€.
- 리μ€νΈμμ κ° Post κ°μ²΄μ λν΄ post.getBlog().getTitle() λ©μλλ₯Ό νΈμΆν λλ§λ€, κ°κ°μ Post κ°μ²΄μ λν΄ κ°λ³μ μΌλ‘ Blogλ₯Ό λ‘λνλ μΆκ° μΏΌλ¦¬κ° μ€νλλ€. (Nλ²μ 쿼리 λ°μ)
κ²°κ³Όμ μΌλ‘ 첫λ²μ§Έ Post κ°μ²΄λ₯Ό λ‘λνλ 쿼리 1κ°μ κ° Post κ°μ²΄μ Blogλ₯Ό λ‘λνλ μΆκ°μ μΈ μΏΌλ¦¬ Nκ°(κ° Post λ§λ€ 1κ°)κ° λ°μνκ² λμ΄ μ΄ N+1νμ μΏΌλ¦¬κ° λ°μνκ² λ©λλ€.
μ΄λ° JPA N+1 λ¬Έμ λ fetch νμ μ΄ μμΈμΈ κ²μ μλμ§λ§(μ¦μ λ‘λ©, μ§μ° λ‘λ© λͺ¨λ λ°μν μ μμ) μ¦μ λ‘λ©μΌ κ²½μ°, νΉν κ°λ°μκ° μ μ΄ν μ μλ μΏΌλ¦¬κ° μ€νλκ³ λ μμ£Ό N+1λ¬Έμ μ λ§μ£ΌνκΈ° λλ¬Έμ μ¬μ©μ μ§μνλ€κ³ νλ€μ
μ΄λ €μ΄ λ΄μ©μ΄ μμλ€λ©΄ μ΄λ₯Ό μ΄λ»κ² ν΄κ²°νμλμ?
- ꡬκΈλ§κ³Ό μ νλΈ