1 ๋ถ„ ์†Œ์š”

FetchType ๐Ÿค” ?


์ž๋ฐ”์—์„œ DB์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ์œ„ํ•ด ์ž๋ฐ” ํผ์‹œ์Šคํ„ด์Šค API(JPA)๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, FetchType์€ ์—”ํ„ฐํ‹ฐ ๊ฐ„์˜ ์—ฐ๊ด€ ๊ด€๊ณ„๋ฅผ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

  • ์—”ํ„ฐํ‹ฐ ๊ฐ„์˜ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์ด ๋˜์–ด ์žˆ์œผ๋ฉด(FK) ๊ทธ ํ•œ ์—”ํ„ฐํ‹ฐ๋ฅผ ์กฐํšŒ์‹œ ๋‹ค๋ฅธ ์—”ํ„ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋•Œ ๋‹ค๋ฅธ ์—”ํ„ฐํ‹ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ถˆ๋Ÿฌ์˜ฌ ๊ฒƒ์ธ๊ฐ€๋ฅผ ์„ค์ •
  • JPA์—์„œ๋Š” ๋‘ ๊ฐ€์ง€ FetchType์ด ์žˆ๋‹ค. EAGER OR LAZY
  • EAGER : ์—ฐ๊ด€๋œ ์—”ํ„ฐํ‹ฐ๋ฅผ ์ฆ‰์‹œ ๋กœ๋”ฉ. ๋”ฐ๋ผ์„œ ํ•ด๋‹น ์—”ํ„ฐํ‹ฐ๊ฐ€ ๋กœ๋“œ๋˜๋Š” ์‹œ์ ์— ์—ฐ๊ด€๋œ ์—”ํ„ฐํ‹ฐ๋„ ํ•จ๊ป˜ ๋กœ๋“œ

    ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฒŒ์‹œํŒ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฒŒ์‹œ๋ฌผ(Board)์™€ ๋Œ“๊ธ€(Reply)๊ฐ€ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ ํ•œ ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ธ๋ณด๊ธฐํ™”๋ฉด์—์„œ ๊ฒŒ์‹œ๋ฌผ๊ณผ ๋Œ“๊ธ€ ๋ชจ๋‘ ํ•œ๊บผ๋ฒˆ์— ๋ณด์—ฌ์งˆ ๋•Œ ์‚ฌ์šฉ๊ฐ€๋Šฅ

  • LAZY : ์—ฐ๊ด€๋œ ์—”ํ„ฐํ‹ฐ๋Š” ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋  ๋•Œ๊นŒ์ง€ ๋กœ๋”ฉ๋˜์ง€ ์•Š์Œ. ๋”ฐ๋ผ์„œ ์—ฐ๊ด€๋œ ์—”ํ„ฐํ‹ฐ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์— ๋กœ๋”ฉ๋˜์–ด ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•จ.

    ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฒŒ์‹œํŒ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฒŒ์‹œ๋ฌผ(Board)์™€ ๋Œ“๊ธ€(Reply)๊ฐ€ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ ํ•œ ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ธ๋ณด๊ธฐํ™”๋ฉด์—์„œ ๊ฒŒ์‹œ๋ฌผ์€ ๋จผ์ € ๋ถˆ๋Ÿฌ์™€์ง€๊ณ  ๋Œ“๊ธ€์„ ํŽผ์ณ๋ณด๊ธฐ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•ด์„œ ๋ฐ”๋กœ ๋ณด์—ฌ์งˆ ํ•„์š”๊ฐ€ ์—†์„ ๋•Œ ์‚ฌ์šฉ๊ฐ€๋Šฅ

  • JPA FetchType default๊ฐ’์€ @xxToOne : EAGER, @xxToMany : LAZY

1. EAGER (์ฆ‰์‹œ๋กœ๋”ฉ)


๋‹ค์Œ๊ณผ ๊ฐ™์ด Member ์—”ํ„ฐํ‹ฐ์™€ Team ์—”ํ„ฐํ‹ฐ๊ฐ€ N:1 ๋งคํ•‘์œผ๋กœ ๊ด€๊ณ„๋ฅผ ๋งบ๊ณ  ์žˆ๋‹ค.

@Entity
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;

    @ManyToOne(fetch = FetchType.EAGER) //Team์„ ์กฐํšŒํ•  ๋•Œ ์ฆ‰์‹œ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•˜๊ณ˜๋‹ค!
    @JoinColumn(name = "team_id")
    Team team;
}

@Entity
public class Team {

    @Id @GeneratedValue
    private Long id;
    private String teamname;
}

JPQL๋กœ Member 1๊ฑด ์กฐํšŒ

Member findMember = em.createQuery("select m from Member m", Member.class).getSingleResult();

์‹ค์ œ SQL ์ฝ”๋“œ

//๋ฉค๋ฒ„๋ฅผ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ
select
    member0_.id as id1_0_,
    member0_.team_id as team_id3_0_,
    member0_.username as username2_0_
from
    Member member0_

//ํŒ€์„ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ
select
    team0_.id as id1_3_0_,
    team0_.name as name2_3_0_
from
    Team team0_
where
    team0_.id=?

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฆ‰์‹œ ๋กœ๋”ฉ(EAGER) ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด Member๋ฅผ ์กฐํšŒํ•˜๋Š” ์‹œ์ ์— ๋ฐ”๋กœ Team๊นŒ์ง€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ ค ํ•œ๊บผ๋ฒˆ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

2. EAGER (์ฆ‰์‹œ๋กœ๋”ฉ)

์•„๋ž˜์™€ ๊ฐ™์ด ์ง€์—ฐ ๋กœ๋”ฉ์œผ๋กœ ์„ค์ •ํ•˜๊ณ  Member๋ฅผ ์กฐํšŒํ•ด๋ณด๋ฉด ์ฆ‰์‹œ ๋กœ๋”ฉ ๋ฐฉ์‹๊ณผ ๋‹ฌ๋ฆฌ Team์„ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š๊ณ  Member๋ฅผ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๋งŒ ๋‚˜๊ฐ€๊ณ , ์‹ค์ œ๋กœ ํŒ€์„ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์— Team์„ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ„๋‹ค.


 @ManyToOne(fetch = FetchType.LAZY) //Team์„ ์กฐํšŒํ•  ๋•Œ ์ง€์—ฐ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•˜๊ณ˜๋‹ค!
 @JoinColumn(name = "team_id")
 Team team;

JPQL๋กœ Member์กฐํšŒ

Member findMember = em.createQuery("select m from Member m", Member.class).getSingleResult();

์‹ค์ œ SQL ์ฝ”๋“œ

//Team์„ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€์ง€ ์•Š์Œ!
select
    member0_.id as id1_0_,
    member0_.team_id as team_id3_0_,
    member0_.username as username2_0_
from
    Member member0_

์ง€์—ฐ ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•˜๋ฉด Member๋ฅผ ์กฐํšŒํ•˜๋Š” ์‹œ์ ์ด ์•„๋‹Œ ์‹ค์ œ Team์„ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์— ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

์œ„ ์˜ˆ์ œ์˜ ์ฆ‰์‹œ ๋กœ๋”ฉ์—์„œ๋Š” Member์™€ ์—ฐ๊ด€๋œ Team์ด 1๊ฐœ์—ฌ์„œ Team์„ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๊ฐ€ 1๊ฐœ ๋‚˜๊ฐ”์ง€๋งŒ, ๋งŒ์•ฝ Member๋ฅผ ์กฐํšŒํ•˜๋Š” JPQL์„ ๋‚ ๋ ธ๋Š”๋ฐ ์—ฐ๊ด€๋œ Team์ด 1000๊ฐœ๋ผ๋ฉด? Member๋ฅผ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ํ•˜๋‚˜ ๋‚ ๋ ธ์„ ๋ฟ์ธ๋ฐ Team์„ ์กฐํšŒํ•˜๋Š” SQL ์ฟผ๋ฆฌ 1000๊ฐœ๊ฐ€ ์ถ”๊ฐ€๋กœ ๋‚˜๊ฐ€๊ฒŒ ๋œ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๊ธ‰์ ์ด๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์—ฐ ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

ํƒœ๊ทธ:

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ