๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๊ณต๋ถ€/Spring

[JPA] ํŽ˜์น˜ ์กฐ์ธ

by JERO__ 2022. 7. 18.

๐Ÿฑ‍๐ŸํŽ˜์น˜ ์กฐ์ธ๐Ÿฑ‍๐Ÿ JOIN FETCH (์ฆ‰์‹œ๋กœ๋”ฉ)

  • SQL ์กฐ์ธ ์ข…๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • JPQL์—์„œ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ
  • ์—ฐ๊ด€๋œ ์—”ํ‹ฐํ‹ฐ๋‚˜ ์ปฌ๋ ‰์…˜์„ SQL ํ•œ๋ฒˆ์— ํ•จ๊ป˜ ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ
  • N+1 ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ๋‹ค.
    1. ํšŒ์› ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„, ๊ฐ ํšŒ์›์ด ์†ํ•œ ํŒ€์„ ์ถœ๋ ฅํ•œ๋‹ค.
    2. ๊ฐ ํšŒ์›์ด ์†ํ•œ ํŒ€์„ ํ˜ธ์ถœํ• ๋•Œ๋งˆ๋‹ค ์ถ”๊ฐ€๋กœ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

1. ์—”ํ‹ฐํ‹ฐ ํŽ˜์น˜ ์กฐ์ธ

ํšŒ์›์„ ์กฐํšŒํ•˜๋ฉด์„œ ์—ฐ๊ด€๋œ ํŒ€๋„ ํ•จ๊ป˜ ์กฐํšŒ

[SQL]
SELECT M.*, T.* FROM MEMBER M           // select M.*, T.*
INNER JOIN TEAM T ON M.TEAM_ID=T.ID

์ฝ”๋“œ๋กœ ์ ์šฉ

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

// ์ถœ๋ ฅ
for (Member member : members) {
	System.out.println("username = " + member.getUsername() + ", " + 
	"teamName = " + member.getTeam().name()); 
}

join fetch๊ฐ€ ์•„๋‹ˆ์—ˆ๋‹ค๋ฉด? member.getTeam()๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆผ

2. ์ปฌ๋ ‰์…˜ ํŽ˜์น˜ ์กฐ์ธ

ํŒ€์„ ์กฐํšŒํ•˜๋ฉด์„œ ์†ํ•œ ํšŒ์›๋„ ํ•จ๊ป˜ ์กฐํšŒ

[JPQL]
select t
from Team t join fetch t.members                     // t.members
where t.name = 'ํŒ€A'
[SQL]
SELECT T.*, M.*                                     // T, M
FROM TEAM T
INNER JOIN MEMBER M ON T.ID=M.TEAM_ID
WHERE T.NAME = 'ํŒ€A'

์ฃผ์˜ํ•  ์ 

TEAM์˜ ์ค‘๋ณต์ด ๋ฐœ์ƒํ•œ๋‹ค. ์ปฌ๋ ‰์…˜์„ ์กฐ์ธํ–ˆ๊ธฐ ๋•Œ๋ฌธ

select distinct t                                   // distinct๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
from Team t join fetch t.members
where t.name = ‘ํŒ€A’

ํŽ˜์น˜์กฐ์ธ vs ์ผ๋ฐ˜์กฐ์ธ

์ผ๋ฐ˜์กฐ์ธ : ์—ฐ๊ด€๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ํ•จ๊ป˜ ์กฐํšŒํ•˜์ง€ ์•Š์Œ

SELECT T.*                                 // T๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค
FROM TEAM T
INNER JOIN MEMBER M ON T.ID=M.TEAM_ID 
WHERE T.NAME = 'ํŒ€A

ํŽ˜์น˜์กฐ์ธ : ์ฆ‰์‹œ๋กœ๋”ฉ

ํŽ˜์น˜์กฐ์ธ์˜ ํ•œ๊ณ„

  • ๋ณ„์นญ์„ ์ค„ ์ˆ˜ ์—†๋‹ค.
  • ๋‘˜ ์ด์ƒ์˜ ์ปฌ๋ ‰์…˜์€ ํŽ˜์น˜์กฐ์ธ ํ•  ์ˆ˜ ์—†๋‹ค.
  • ์ปฌ๋ ‰์…˜์„ ํŽ˜์น˜ ์กฐ์ธํ•˜๋ฉด ํŽ˜์ด์ง• API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
    • 1:1, N:1์€ ํŽ˜์น˜์กฐ์ธํ•ด๋„ ํŽ˜์ด์ง• ๊ฐ€๋Šฅํ•˜๋‹ค.
    • 1:N์˜ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
    • ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์€? ํŽ˜์น˜์กฐ์ธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , BatchSize๋ฅผ ์„ค์ •ํ•œ๋‹ค.
    @BatchSize(size=100)
    @OneToMany(mappedBy="team")
    private List<Member> members = new ArrayList<>();
    

๋Œ“๊ธ€