JAVA

[JAVA] 즉시로딩과 지연로딩

응디 2022. 1. 5. 17:16

지연로딩

  • Member만 조회하고 싶은데 굳이 Team까지 가져와야하나?? 지연로딩 사용!
  • 지연로딩 : Member만 조회해옴!
  • LAZY를 사용해서 프록시로 조회
/* Member.java */
@ManyToOne(fetch = FetchType.LAZY)  // Member 클래스만 DB에서 조회한다.
@JoinColumn
private Team team;

/* Main.java */
Team team = new Team();
team.setName("teamA");

em.persist(team);

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

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

Member m = em.find(Member.class, member1.getId());

System.out.println("m = " + m.getTeam().getClass());     // 프록시네??

System.out.println("====================================");

m.getTeam().getName();  // 프록시 초기화 (쿼리 날림)

System.out.println("=====================================");

 


즉시로딩

  • 만약 Member와 Team을 같이 사용 할 일이 많다면??? → 즉시로딩!
  • 즉시 로딩 : Member + Team 같이 조회함 → EAGER 사용함!
  • em.find때 부터 Team 데이터 까지 몽땅 가져옴
/* Member.java */
@ManyToOne(fetch = FetchType.EAGER)  // Member 클래스만 DB에서 조회한다.
@JoinColumn
private Team team;


프록시와 즉시로딩 주의

실무에서는 가급적 지연로딩만 사용

  • 즉시 로딩을 적용하면 예상하지 못한 SQL 발생 ( 테이블이 10개가 join 되면 엄청난 쿼리가 발생할수있음..)
  • 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다.

em.find는 Id를 가지고 알아서 다 select 하기 때문에 Member와 Team을 한문장으로 알아서 찾지만, JPQL은 적혀진 쿼리 가지고 행동하기 때문에 아래와 같은 쿼리로 10명의 Team을 찾으려면 쿼리가 10개 이상 나갈 수 있다.

List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();

 

이 경우 쿼리가 아래처럼 두번 나가게 된다(회원이 한명일때 )

SQL : select * from Member
SQL : select * from Team where TEAM_ID = XXX

만약 회원 두명이 서로 다른 팀을 가지고 있다면??

member는 한번에 가져오고, 2명의 member가 각기 다른 팀이기때문에 team 쿼리를 두번 날린다.

이 부분을 LAZY(지연로딩)으로 변경한다면?

지연로딩 예시

member 쿼리만 생성됨 → Team을 사용하지 않기 때문!

해결방안 : join fetch 사용! (뒤에서 자세히 설명)

List<Member> members = em.createQuery("select m from Member m join fetch m.team", Member.class).getResultList();

 

@ManyToOne, @OneToOne은 기본이 즉시로딩이다 → LAZY(지연로딩)으로 설정해줘야함!
@OneToMany, @ManyToMany는 기본이 지연로딩: 지연로딩 사용!

 

'JAVA' 카테고리의 다른 글

[JAVA] 임베디드 타입(복합값)  (0) 2022.01.11
[JAVA] 영속성 전이(CASCADE) + 고아객체  (0) 2022.01.06
[JAVA] 프록시  (0) 2022.01.04
[JAVA] @MappedSuperclass  (0) 2022.01.04
[JAVA] JPA 고급 매핑 (상속 관계 매핑)  (0) 2021.12.16