Search
Duplicate
๐ŸŽจ

๋„๋ฉ”์ธ ๊ตฌ์กฐ ์šฐ์•„ํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜๊ธฐ

์ƒ์„ฑ์ผ
2022/11/29
ํƒœ๊ทธ
Refactoring
Spring
Structure
JPA
๋ชฉ์ฐจ

๋ฐฐ๊ฒฝ

์ €ํฌ ๋ชจ๋ฝ์€ ์Šคํ”„๋ฆฐํŠธ 5๋ฅผ ์‹œ์ž‘ํ•˜๋ฉด์„œ ์š”๊ตฌ ์‚ฌํ•ญ ์ด์™ธ์— ํ•จ๊ป˜ ํ•ด์•ผ ํ•  ์ผ๋“ค์— ๋Œ€ํ•ด ํšŒ์˜๋ฅผ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์บ์‹ฑ ์„œ๋ฒ„, ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ๋“ฑ ํฅ๋ฏธ๋กœ์šด ์ฃผ์ œ๋“ค์ด ๋‚˜์™”๋Š”๋ฐ ๊ทธ ์ค‘์—์„œ๋„ ๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„์— ๋Œ€ํ•œ ์š•๊ตฌ๊ฐ€ ๊ฐ€์žฅ ์ปธ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ฐฑ์—”๋“œ ํŒ€์›์ด ๋„๋ฉ”์ธ์— ๋Œ€ํ•œ ๋Œ€๊ณต์‚ฌ๋ฅผ ์›ํ•˜๊ธฐ๋„ ํ–ˆ๊ณ , ๊ณ„์ธต ๊ตฌ์กฐ ์žฌ์„ค๊ณ„์— ๋Œ€ํ•œ ํฅ๋ฏธ๋„ ์ปธ๊ธฐ๋•Œ๋ฌธ์— ์ด๋ฒˆ ์Šคํ”„๋ฆฐํŠธ 5์—์„œ ๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„๋ฅผ ๋Œ€๋Œ€์ ์œผ๋กœ ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ผ์ • ์ƒ์œผ๋กœ ์ผ๊ณผ ์ค‘์—๋Š” ์ธ๋ฑ์Šค, ์“ฐ๋ ˆ๋“œ ์„ค์ •์„ ํฌํ•จํ•œ ์š”๊ตฌ ์‚ฌํ•ญ, ์ผ๊ณผ ํ›„์™€ ์ฃผ๋ง์—๋Š” ๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ์ 

๋จผ์ € ์Šคํ”„๋ฆฐํŠธ 1-4๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋Š๋‚€ ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์— ๋Œ€ํ•ด ๊ณต์œ ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
โ€ข
์˜์กด ๊ด€๊ณ„๊ฐ€ ์–ฝํ˜€์žˆ๋‹ค.
โ—ฆ
Poll ย PollItem, PollItem ย PollResult ๋“ฑ ์„œ๋กœ๊ฐ€ ์„œ๋กœ๋ฅผ ๋„ˆ๋ฌด ์ž˜ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
โ€ข
์„œ๋น„์Šค ๊ณ„์ธต ํ•˜๋‚˜์— ๋งŽ์€ ๋กœ์ง์ด ์ง‘์ค‘๋œ ๊ตฌ์กฐ์ด๋‹ค. โ†’ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ์—ญํ• ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋กœ ๋ชจ๋“  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์•ฝ์†์žก๊ธฐ์˜ ์ผ๊ทธ๋Ÿฌ์ง„ ์˜์›…
์œ„์˜ ์ƒํ™ฉ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋กœ๋Š” ์ƒํ˜ธ ์ฐธ์กฐํ•˜๋Š” ๊ตฌ์กฐ๋กœ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ต๋‹ค๋Š” ์ ๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์„œ๋น„์Šค ๊ณ„์ธต์— ์žˆ์–ด ์‘์ง‘๋„๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค๋Š” ์  ๋“ฑ 2๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹จ๋ฐฉํ–ฅ ์˜์กด์„ฑ์„ ๊ฐ€์ง€๋Š” ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ํ•˜๊ณ , ๊ฐ€์žฅ ์ค‘์‹ฌ์ด ๋˜๋Š” ๋„๋ฉ”์ธ์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋„ฃ์–ด ์‘์ง‘๋„๋ฅผ ๋†’์—ฌ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ฆฌํŒฉํ† ๋ง์„ ํ•œ๋‹ค๋ฉด ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๊ณ , ์ˆœ์ฐจ์ ์œผ๋กœ ์˜์†ํ™” ๊ณ„์ธต, ์„œ๋น„์Šค ๊ณ„์ธต๋„ ์˜ํ–ฅ์„ ๋ฐ›๊ฒŒ ๋˜๋Š” ์ปค๋‹ค๋ž€ ๊ณต์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ์ƒํ™ฉ์—์„œ ์„œ๋น„์Šค๋„ ์œ ์ง€ํ•ด์•ผ ํ–ˆ๊ธฐ๋•Œ๋ฌธ์— ์•ฝ 4์ฃผ์˜ ๊ธฐ๊ฐ„์„ ์žก๊ณ  ๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„๋ฅผ ์‹œ์ž‘ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ชฉํ‘œ

์„ค๊ณ„ ๋ฐ ๊ฐœ๋ฐœํ•˜๊ธฐ์— ์•ž์„œ ์šฐ๋ฆฌ์˜ ๋ชฉํ‘œ๋ถ€ํ„ฐ ์ƒˆ๋กœ ๋‹ค์žก๊ณ  ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋จผ์ €์˜€์Šต๋‹ˆ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ์„ค๊ณ„ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์งค ๋•Œ ์ปจ์…‰์„ ์žก๊ณ  ํ•ญ์ƒ ์šฐ๋ฆฌ์˜ ์ฒ ์น™๊ณผ ์ด์œ ๋ฅผ ์ƒ๊ฐํ•˜๊ณ  ์ •๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค.
โ†’ ๋ชจ๋“  ์ฝ”๋“œ์— ์ด์œ ์™€ ์†๋•Œ๊ฐ€ ๋ฌป์–ด๋‚˜๋Š” ๊ฒƒ์ด ์ฒซ๋ฒˆ์งธ ๋ชฉํ‘œ์˜€์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐ์—๋Š” ์‹œ๊ฐ„ ๋‚ด์— ์„œ๋น„์Šค๋ฅผ ์™„์„ฑ์‹œ์ผœ์•ผ ํ–ˆ๊ธฐ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ๋ถ€๋žด๋ถ€๋žด ์งฐ๊ณ , ์ดํ›„ ์ง  ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ๋ณด๋ฉด โ€˜์šฐ๋ฆฌ๊ฐ€ ๋ ˆ๋ฒจ 1, 2๋•Œ ๋ญ ๋ฐฐ์› ๋”๋ผโ€™ ๋ผ๋Š” ์ƒ๊ฐ์„ ๋งŽ์ด ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ํ”„๋กœ์ ํŠธ์˜ ์ƒํ™ฉ๊ณผ ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์ฝ”๋“œ ํ€„๋ฆฌํ‹ฐ๋Š” ์ž ์‹œ ์ œ์ณ๋‘๊ณ  ์„œ๋น„์Šค๋ฅผ ์‹œ๊ฐ„ ๋‚ด์— ๊ฐœ๋ฐœํ•˜๋Š”๊ฒŒ ๊ทธ ๋‹น์‹œ์˜ ๋ชฉํ‘œ์˜€์Šต๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ๋ ˆ๊ฑฐ์‹œ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์น˜์šฐ์ž! ๋ผ๋Š” ๋งˆ์ธ๋“œ๋กœ ๋ ˆ๋ฒจ 1, 2๊ธฐ๊ฐ„ ๋ฐฐ์šด ํด๋ฆฐ ์ฝ”๋“œ, ์ž๋ฐ”์˜ ํŠน์ˆ˜์„ฑ ๋“ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์˜๋ฏธ์žˆ๊ณ  ๊น”๋”ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์œ„์˜ ๋ชฉํ‘œ๋ฅผ ์กฐ๊ธˆ ๋” ๊ตฌ์ฒดํ™”ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
โ€ข
์˜์กด์„ฑ ํ๋ฆ„์„ ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.
โ€ข
๋„๋ฉ”์ธ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ฒด์ง€ํ–ฅ์ ์œผ๋กœ ์ƒˆ๋กญ๊ฒŒ ๊ตฌ์ƒํ•ด๋ณด๊ณ  ๊ธฐ์กด์˜ ๊ตฌ์กฐ์™€ ๋น„๊ตํ•ด๋ณธ๋‹ค.
์˜ˆ์™ธ๋ฅผ ๋ฐœ๊ฒฌํ•  ๋•Œ๋งˆ๋‹ค ๊ฒ€์ฆ ๋กœ์ง์„ ์ถ”๊ฐ€ํ•˜๋‹ค๋ณด๋‹ˆ, ์ดํ›„ ํ•ด๋‹น ๋กœ์ง์„ ๋ณผ ๋•Œ ์–ด๋–ค ๊ฒ€์ฆ ๋กœ์ง์ด์—ˆ๋Š”์ง€ ์ €๋„ ํ—ท๊ฐˆ๋ฆด ๋•Œ๊ฐ€ ๋งŽ์•˜์Šต๋‹ˆ๋‹ค(๊ทธ๋Ÿฐ๋ฐ git blame ์„ ๋ณด๋ฉด sungsan kim). ๊ทธ๋ž˜์„œ ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•œ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ณ ์ž ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋งŽ์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋“ค์ด ์„œ๋น„์Šค ๊ณ„์ธต๊ณผ DB ์ฟผ๋ฆฌ์— ์ข…์†์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋กœ์ง๋“ค์„ ๋„๋ฉ”์ธ ๊ฐ์ฒด ๋‚ด๋ถ€์— ๋„ฃ์–ด ์‘์ง‘๋„๋ฅผ ๋†’์ด๊ณ ์ž ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
๋งˆ์ง€๋ง‰์œผ๋กœ ์˜์กด์„ฑ์„ ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ ํ๋ฅด๊ฒŒ ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ ์ž ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋„๋ฉ”์ธ๊ฐ„์— ์–‘๋ฐฉํ–ฅ์„ ๊ฐ€์ง€๊ณ , ์„œ๋น„์Šค ๊ณ„์ธต๊ฐ„์—์„œ ์„œ๋น„์Šค๋ผ๋ฆฌ ์„œ๋กœ ์˜์กดํ•˜๋Š” ๊ตฌ์กฐ๋Š” ์ˆœํ™˜ ์ฐธ์กฐ์— ๋น ์งˆ ์šฐ๋ ค๊ฐ€ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋„๋ฉ”์ธ ์„ค๊ณ„ํ•˜๊ธฐ

๋ฌธ์ œ ์›์ธ ํŒŒ์•…

๊ธฐ์กด์˜ ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ๋Š” ๋ ˆํฌ์ง€ํ† ๋ฆฌ์˜ ๋ฉ”์„œ๋“œ์™€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ํ•จ๊ป˜ ์–ด์šธ๋ ค ๋†€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ์ƒํ™ฉ์ด ํŠน์ˆ˜ํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. JPA ๋ฉ”์„œ๋“œ์™€ ๊ฐ„๋‹จํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์žˆ๋Š” ๊ฒƒ์€ ์ต์ˆ™ํ•˜๊ณ , ์˜คํžˆ๋ ค ๊ฐœ๋ฐœ ์ดˆ๊ธฐ ๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ธฐ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฒ€์ฆ ๋กœ์ง๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋ณต์žกํ•ด์ง€๊ณ , ๋‹ค์–‘ํ•œ JPA ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜๊ฒŒ ๋˜๋ฉด์„œ ์ ์  ์œ ์ง€, ๋ณด์ˆ˜ ํ•˜๊ธฐ๊ฐ€ ํž˜๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋„๋ฉ”์ธ ๊ฐ์ฒด์—๋Š” getter ์™€ ์ƒ์„ฑ์ž๊ฐ€ ๊ฐ€๋“ํ•˜๊ณ  ์ƒ์„ฑ ์‹œ ๊ฒ€์ฆํ•˜๋Š” ๋กœ์ง์ด ์ „๋ถ€์˜€์Šต๋‹ˆ๋‹ค.
๋ ˆ๋ฒจ 1, 2 ๊ณผ์ •์—์„œ ๋ฏธ์…˜์„ ํ•  ๋•Œ์—๋Š” ๋„๋ฉ”์ธ ๊ฐ์ฒด์—์„œ ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋ฅผ ์ž์ฃผ ๋ณด์ง€ ๋ชปํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์™œ ์ด๋ ‡๊ฒŒ ๋˜์—ˆ๋Š”์ง€ ๊ณฐ๊ณฐํžˆ ์ƒ๊ฐํ•ด ๋ณด๋‹ค๊ฐ€ ์ €ํฌ ์„œ๋น„์Šค์˜ ํšŒ์›, ํŒ€ ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋˜ ๋•Œ๋ฅผ ํšŒ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. DB ์Šคํ‚ค๋งˆ๋ฅผ ๋จผ์ € ์„ค๊ณ„๋ฅผ ํ•œ ๋’ค ํ•ด๋‹น ํ…Œ์ด๋ธ”๊ณผ ์—ฐ๊ด€ ๊ด€๊ณ„์— ๋งž์ถฐ ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค๋ณด๋‹ˆ ๊ฐ์ฒด๊ฐ€ ์—ญํ• ๊ณผ ์ฑ…์ž„์„ ๊ฐ€์ง€๋Š” ๊ตฌ์กฐ๊ฐ€ ์•„๋‹ˆ๋ผ, ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์ ์ธ ๊ตฌ์กฐ๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ์ถ”์ธกํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ DB๋ผ๋Š” ๊ฐœ๋…์ด ์—†๋Š” ์ฝ˜์†”์˜ ์„ธ๊ณ„๊ด€์—์„œ, ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์‚ฌ๊ณ ํ•ด๋ณด๊ธฐ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋„๋ฉ”์ธ ์„ค๊ณ„ ์ดˆ์•ˆ

์ „์ฒด ๊ธฐ๋Šฅ์ด ํˆฌํ‘œ, ์•ฝ์†์žก๊ธฐ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์—ˆ๊ณ  ์‹œ๊ฐ„์˜ ํšจ์œจ์„ฑ๊ณผ ํ˜‘์—…์„ ์œ„ํ•ด ๊ฐ ๊ธฐ๋Šฅ์„ ๋‘ ๋ช…์”ฉ ๋งก์•„ ํŽ˜์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๋ฉด์„œ ๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„๋ฅผ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ์—˜๋ฆฌ์™€ ์ €๋Š” ํˆฌํ‘œ, ์ฐจ๋ฆฌ์™€ ๋ฐฐ์นด๋ผ๋Š” ์•ฝ์†์žก๊ธฐ๋ฅผ ๋งก์•˜์Šต๋‹ˆ๋‹ค.
๋„๋ฉ”์ธ์„ ๊ทธ๋ ค๋ณด๊ธฐ ์ „์—, ๊ฑด์ถ•๊ฐ€ ์ˆ˜์ €์ธ ์—˜๋ฆฌ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ง์„ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.
โ€ข
์‹œ๊ณต์ด ์•„๋‹ˆ๋ผ ๋””์ž์ด๋„ˆ์˜ ๊ด€์ ์—์„œ ์ƒ๊ฐํ•ด๋ณธ๋‹ค.
โ€ข
์‹ค๋ ฅ์ด ์Œ“์ด๋ฉด ๋””์ž์ธ์„ ํ•˜๋Š” ๋‹จ๊ณ„์—์„œ๋„ ์‹œ๊ณต์„ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์ด ๋˜์ž!
์ด ๋ง์ด ํฌ๊ฒŒ ์™€๋‹ฟ์•˜์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๊ฑด๋ฌผ์„ ์ง€์„ ๋•Œ์—๋„ ๋””์ž์ด๋„ˆ, ์‹œ๊ณต์‚ฌ ๋“ฑ ๋‹ค์–‘ํ•œ ๋„๋ฉ”์ธ์„ ๊ฐ€์ง„ ์‚ฌ๋žŒ๋“ค์ด ํ˜‘๋ ฅํ•˜์—ฌ ์™„์„ฑํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์— ์ €ํฌ๊ฐ€ ๋งŒ๋“  ๊ฑด๋ฌผ์€ ์‹œ๊ณต์‚ฌ๊ฐ€ ๋””์ž์ธ๊นŒ์ง€ ์ง์ ‘ ๊ฐœ์ž…ํ•˜์—ฌ, ๋น ๋ฅด๊ฒŒ ์ง€์„ ์ˆ˜๋Š” ์žˆ์—ˆ์ง€๋งŒ ๋ฏธ์ ์ธ ์•„๋ฆ„๋‹ค์›€์ด ์—†๋Š” ๊ฒƒ์€ ๋ฌผ๋ก ์ด๊ณ  ์–ด๋””๊ฐ€ ๊ณ„๋‹จ์ด๊ณ  ์–ด๋””๊ฐ€ ๋ฐฉ์ธ์ง€ ์•Œ์•„์ฐจ๋ฆฌ๊ธฐ ํž˜๋“  ๊ตฌ์กฐ์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ๋””์ž์ด๋„ˆ๋งŒ ์žˆ์œผ๋ฉด ์‹œ๊ณต ์‹œ์— ํ•„์š”ํ•œ ํšจ์œจ์ ์ธ ๊ณ„๋‹จ ์ˆ˜, ์ง€ํƒฑํ•  ์ˆ˜ ์žˆ๋Š” ์ž์žฌ ๋“ฑ์„ ์‹ค์ œ ๊ฑด์„ค ํ˜„์žฅ์—์„œ ์•Œ์•„์ฐจ๋ฆฌ๊ธฐ๋Š” ํž˜๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ฒ˜์Œ์—๋Š” ๋””์ž์ด๋„ˆ์˜ ์ž…์žฅ์—์„œ ๊ฑด๋ฌผ ๋‚ด ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•œ ์œ„์น˜์™€ ์ „์ฒด์ ์ธ ๊ตฌ์กฐ ๋“ฑ์— ๋Œ€ํ•ด ๋””์ž์ธํ•˜๊ณ , ์‹ค์ œ ๊ฑด๋ฌผ์„ ์ง€์„ ๋•Œ์—๋Š” ๋งŒ๋“ค์–ด ๋†“์€ ๋””์ž์ธ์„ ๋ฐ”ํƒ•์œผ๋กœ ์‹ค์ œ ํ˜„์žฅ์˜ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ˆ˜์ •์„ ํ•˜๋ฉด์„œ ๋ฆฌ๋ชจ๋ธ๋ง์„ ์™„์„ฑํ•ด ๋ณด๊ธฐ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
โ€ข
์ด์ „ ๋„๋ฉ”์ธ ๊ตฌ์กฐ
โ€ข
์ƒˆ๋กœ์šด ๋„๋ฉ”์ธ ๊ตฌ์กฐ ์ดˆ์•ˆ
๊ฐ ๋„๋ฉ”์ธ์€, ์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. member๊ฐ€ team์— ์†ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋กœ์ง์€ ๊ณตํ†ต ๋กœ์ง์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๊ฒ€์ฆ ๋กœ์ง์„ ๊ธฐ์กด ๋„๋ฉ”์ธ์—์„œ ๋ถ„๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ Member ์™€ Team ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋กœ์ง์ด ์—†๊ธฐ๋•Œ๋ฌธ์— Member ์™€ Team ๊ฐ์ฒด๋ฅผ ๊ฐ„์ ‘ ์ฐธ์กฐ๋กœ ๋ฐ”๊พธ์–ด ์˜์กด๋„๋ฅผ ๋‚ฎ์ถ”์—ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์–‘๋ฐฉํ–ฅ์œผ๋กœ ์ฐธ์กฐํ•˜๋˜ ๊ตฌ์กฐ๋ฅผ ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ”๊พธ์—ˆ์Šต๋‹ˆ๋‹ค. Poll Item ๊ฐ์ฒด์—์„œ Poll ์— ๋Œ€ํ•œ ์˜์กด์„ ๋ถ„๋ฆฌํ•˜์˜€๋Š”๋ฐ, ์˜ˆ๋ฅผ ๋“ค์–ด Poll Item ์—์„œ๋Š” Poll ์— ์žˆ๋Š” ํˆฌํ‘œ ์ œ๋ชฉ ๋“ฑ๊ณผ ๊ฐ™์€ ์ •๋ณด๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋กœ์ง์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— Poll Item ์—์„œ Poll ์„ ์ฐธ์กฐํ•  ํ•„์š”๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Select Members(๊ตฌ Poll Result) ๋Š” ์ž์‹ ์ด ์–ด๋–ค Poll Item์— ํˆฌํ‘œํ–ˆ๋Š”์ง€ ์•Œ ํ•„์š”๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ํˆฌํ‘œ ํ•ญ๋ชฉ ๋‚ด์šฉ์€ ์„ ํƒ ์ธ์›(ํˆฌํ‘œ ๊ฒฐ๊ณผ)์—์„œ ์•Œ ํ•„์š” ์—†์ด, ํˆฌํ‘œํ•œ ๋ฉค๋ฒ„์™€ ํˆฌํ‘œ ์ด์œ ๋งŒ ์•Œ๋ฉด ๋˜๊ธฐ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ Select Members ์—์„œ๋„ Poll Item ์— ๋Œ€ํ•œ ์˜์กด๋„ ๋ถ„๋ฆฌํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„ JPA ์ ์šฉ

๋จผ์ € ์„ค๊ณ„ํ•œ ์ด๋ฏธ์ง€์— ๋งž์ถฐ ๋„๋ฉ”์ธ ๊ฐ์ฒด์™€ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“  ๋’ค, JPA ์— ์ ์šฉํ•ด ๋ณด๊ณ ์ž ํ•˜์˜€์Šต๋‹ˆ๋‹ค. JPA ์ ์šฉ ์‹œ ์ฃผ์˜๊นŠ๊ฒŒ ๋ด์•ผํ•  ๋ถ€๋ถ„์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
โ€ข
์˜์กดํ•œ field ๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ column ๊ณผ ์—ฐ๊ด€ ๊ด€๊ณ„๋กœ ์ ์šฉ๋˜๋Š”๊ฐ€
โ€ข
๋„๋ฉ”์ธ ๋กœ์ง์œผ๋กœ ์ถ”๊ฐ€, ๋ณ€๊ฒฝ, ์‚ญ์ œ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์ ์šฉ๋˜๋Š”๊ฐ€
๊ฐ’ ๊ฐ์ฒด์™€ ์ผ๊ธ‰ ์ปฌ๋ ‰์…˜์œผ๋กœ ํฌ์žฅํ•œ ๊ฐ์ฒด์— ๋Œ€ํ•ด JPA ๋Š” @Embedded, @ElementCollection ๊ณผ ๊ฐ™์€ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ํ™•์ธํ•˜๊ณ  ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋„๋ฉ”์ธ ๋กœ์ง์œผ๋กœ ์ธํ•ด ๋ณ€๊ฒฝ๋œ ์‚ฌํ•ญ์— ๋Œ€ํ•ด์„œ๋Š” ๋”ฐ๋กœ update ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ๋Š” ๋Œ€์‹ , JPA ๊ฐ€ dirty checking ์œผ๋กœ ๋ณ€๊ฒฝ์ ์„ ํ™•์ธํ•˜๊ณ  ๋ณ€๊ฒฝ ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ตฌ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.
โ€ข
@Embedded, @Embeddable
๊ฒ€์ฆ ๋กœ์ง๊ณผ ๋„๋ฉ”์ธ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด title, items ๋“ฑ์˜ ๋ณ€์ˆ˜๋Š” ๊ฐ’๊ฐ์ฒด์™€ ์ผ๊ธ‰ ์ปฌ๋ ‰์…˜ ๊ฐ์ฒด๋กœ ํฌ์žฅํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋Š” ๋ฌผ๋ก  DB ์˜ ํƒ€์ž…์œผ๋กœ ์—†๊ธฐ์—, ํ•ด๋‹น ๊ฐ์ฒด ๋‚ด๋ถ€์˜ DB ํƒ€์ž…๊ณผ ๋งคํ•‘๋  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ฐพ๊ณ , ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ DB ์˜ column ์œผ๋กœ ์„ ์ •ํ•ฉ๋‹ˆ๋‹ค.
โ€ข
@ElementCollection
Specifies a collection of instances of a basic type or embeddable class.
์ปฌ๋ ‰์…˜์„ ๊ฐ’ ํƒ€์ž…์œผ๋กœ ์ €์žฅํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€์ƒ์€ @OneToMany ๊ฐ€ ์žˆ๋Š”๋ฐ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ ์ปฌ๋ ‰์…˜์˜ ์ œ๋„ค๋ฆญ์œผ๋กœ ์„ ์ •๋˜๋Š” ํƒ€์ž…์ด @Entity ์ธ์ง€ @Embedded ๋˜๋Š” ๊ธฐ๋ณธ ํƒ€์ž…(String, Integer)์ธ์ง€์˜ ์ฐจ์ด์ž…๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ด€์ ์œผ๋กœ ๋ณด์•˜์„ ๋•Œ๋กœ ์ฐจ์ด์ ์„ ์ƒ๊ฐํ•ด๋ณด๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์œ ์ผํ•˜๊ณ  ๋‹ค๋ฅธ ๊ฐ์ฒด์™€ ๊ตฌ๋ถ„์ด ๋˜๊ณ  ๋…์ž์ ์ธ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง€๋Š” ์„ฑ๊ฒฉ์„ ์ง€๋‹ˆ๋Š”์ง€, ์•„๋‹ˆ๋ฉด ๋‹ค๋ฅธ ๊ฐ์ฒด์— ์†ํ•˜๊ณ , ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ์†Œ์†๋œ ๊ฐ์ฒด์— ์ข…์†์ ์ธ์ง€๋กœ ํŒ๋‹จํ•˜์˜€์Šต๋‹ˆ๋‹ค.
SelectMembers ๋ผ๋Š” ๋„๋ฉ”์ธ ๊ฐ์ฒด๋Š” ๊ฐ๊ฐ์˜ ํˆฌํ‘œ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ํˆฌํ‘œ ์ด์œ ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ํ•ด๋‹น ๊ฐ์ฒด์—์„œ๋Š” ์ปฌ๋ ‰์…˜ ํƒ€์ž…์œผ๋กœ ์•ž์„œ ์–ธ๊ธ‰ํ•œ ํŒ๋‹จ์—์„œ ํ›„์ž์— ์†ํ•˜์—ฌ @ElementCollection ์„ ์‚ฌ์šฉํ•˜์˜€๋Š”๋ฐ์š”, ์กฐ๊ธˆ ํŠน์ดํ•œ ์ ์€ ์ปฌ๋ ‰์…˜ ์ค‘ Map ์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ ํˆฌํ‘œ ํ•ญ๋ชฉ์ธ Poll Item ์ž…์žฅ์—์„œ ๋ณด์•˜์„ ๋•Œ ์ž์‹ ์„ ํˆฌํ‘œํ•œ ์‚ฌ์šฉ์ž์™€, ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ํˆฌํ‘œ ํ•ญ๋ชฉ์„ ์„ ํƒํ•œ ์ด์œ ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ์ด ํƒ€๋‹นํ•˜๊ณ , ํˆฌํ‘œ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ์‚ฌ์šฉ์ž๋Š” ํ•œ ๋ฒˆ๋งŒ ํˆฌํ‘œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‹ค์‹œ ํˆฌํ‘œํ•œ๋‹ค๋ฉด ์ด๋Š” ํˆฌํ‘œ ์žฌ์„ ํƒ์ด๋ผ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋˜์–ด, ๊ธฐ์กด์˜ ํ•ด๋‹น ํˆฌํ‘œ ํ•ญ๋ชฉ์—์„œ ์„ ํƒํ•œ ๋ฉค๋ฒ„(Map ์˜ Key)๋ฅผ ์ฐพ๊ณ , ๊ธฐ์กด์˜ ํˆฌํ‘œ ์ด์œ (Value)๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  JPA ๋Š” ์ด๋Ÿฌํ•œ Map ๊ณผ ๊ฐ™์€ ์ปฌ๋ ‰์…˜๋„ ๊น”๋”ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด ์ค๋‹ˆ๋‹ค.
โ€ข
@CollectionTable
Specifies the table that is used for the mapping of collections of basic or embeddable types.
@ElementCollection ์„ ์•„์ฃผ ๋‹จ์ˆœํ•˜๊ฒŒ ์ƒ๊ฐํ•˜์—ฌ ์—ฐ๊ด€ ๊ด€๊ณ„ ๋งคํ•‘์„ ํ•œ๋‹ค ๋ฅผ JPA์— ์•Œ๋ ค์ฃผ๋Š” ๊ฑฐ๋ผ๋ฉด, @CollectionTable ์€ ์ƒˆ๋กœ ์ƒ์„ฑ๋˜๋Š” ์ปฌ๋ ‰์…˜ ํƒ€์ž…์— ๋Œ€ํ•œ ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ๋ถ€๊ฐ€ ์ •๋ณด๋ฅผ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ž…๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ๋ณ€์ˆ˜ ๋ช…์ด selectMembers ๋ผ์„œ ํ…Œ์ด๋ธ” ๋ช…์œผ๋กœ select_members ๊ฐ€ ๋“ค์–ด๊ฐˆ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ €ํฌ๋Š” ํ…Œ์ด๋ธ” ๋ช…์€ ๋‹จ์ˆ˜๋กœ ํ†ต์ผํ–ˆ๊ธฐ๋•Œ๋ฌธ์— name = "select_member" ๋ผ๋Š” ์˜ต์…˜์„ ๋„ฃ์–ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. (์ถ”๊ฐ€. ํฌ์ŠคํŒ…์„ ํ•˜๋ฉด์„œ name ์˜ต์…˜์„ ๋–ผ๊ณ  ์‹คํ–‰ํ•ด๋ณด๋‹ˆ, poll_item_select_members ๋ผ๋Š” ํ…Œ์ด๋ธ” ๋ช…์œผ๋กœ ๋งคํ•‘ ํ…Œ์ด๋ธ” ์ด๋ฆ„์ฒ˜๋Ÿผ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค)
JPA ํ…Œ์ด๋ธ” ์ƒ์„ฑ์„ ์œ„ํ•œ ๊ธฐ๋ณธ์ ์ธ ์„ธํŒ…์ด ์™„๋ฃŒ๋˜์–ด ddl-auto ์˜ต์…˜์„ create-drop ์œผ๋กœ ์ž ์‹œ ๋ณ€๊ฒฝํ•œ ๋’ค ๋กœ์ปฌ ์„œ๋ฒ„์—์„œ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ 1. ๋ถˆํ•„์š”ํ•œ ๋งคํ•‘ ํ…Œ์ด๋ธ” ์ƒ์„ฑ

Poll ๊ณผ Poll Item ์‚ฌ์ด ๊ตฌ์กฐ๋Š” @OneToMany ๋‹จ๋ฐฉํ–ฅ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ Poll Item ์— ๋Œ€ํ•œ ์ œ์–ด๊ถŒ์„ Poll ์ด ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ DB ์—์„œ๋Š” ์ด์™€ ๊ฐ™์€ ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Poll ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ Poll Item ์ด ์™ธ๋ž˜ํ‚ค๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ @ManyToOne ์ด๋ผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด ์—†๋‹ค๋ฉด JPA ๋Š” ์ฐธ์กฐ ํ…Œ์ด๋ธ”์— ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋Œ€์‹ , ๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋งคํ•‘ ํ…Œ์ด๋ธ”์„ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
// ์ƒ์„ฑ๋œ ๋งคํ•‘ ํ…Œ์ด๋ธ”. create table poll_values ( poll_id bigint not null, values_id bigint not null ) // auto increment ๋˜๋Š” PK ์—†์ด poll item id ์— unique ์ œ์•ฝ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•œ๋‹ค. alter table poll_values add constraint UK_svhq3p4dudwno4rl9gqxv0ohr unique (values_id) alter table poll_values add constraint FKklk455ytxmer2rri215keq7l9 foreign key (values_id) references poll_item alter table poll_values add constraint FKhfe8b8s1xteaqqeoakyb1jkap foreign key (poll_id) references poll
Java
๋ณต์‚ฌ
ํ•˜์ง€๋งŒ Poll ๊ณผ Poll Item ๊ด€๊ณ„๋Š” ์ผ๋Œ€๋‹ค ๊ด€๊ณ„์ด๊ธฐ๋•Œ๋ฌธ์— ๊ตณ์ด ๋งคํ•‘ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  @ManyToOne ์„ ์ ์šฉํ•˜๋ฉด ์–‘๋ฐฉํ–ฅ์œผ๋กœ ํ๋ฅด๊ฒŒ ๋˜๊ณ , @ManyToOne ๋‹จ๋ฐฉํ–ฅ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ™˜๊ฒฝ์—์„œ ์ œ์–ด๊ถŒ์„ Poll Item ์— ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ง€๊ธˆ์˜ ๊ตฌ์กฐ์—์„œ ๊ธฐ์ˆ ์ ์œผ๋กœ ํ’€์–ด๋‚ด์•ผ ํ•ด์„œ ๊ณ ๋ฏผํ•˜๋˜ ์™€์ค‘์— 3๊ธฐ์˜ ์†๋„ˆ์ž˜๋กœ๋ถ€ํ„ฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๋“ฃ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
@OneToMany(cascade = CascadeType.ALL) @JoinColumn(name = "poll_id", nullable =false, updatable =false) private List<NewPollItem> values =new ArrayList<>();
Java
๋ณต์‚ฌ
@JoinColumn ์–ด๋…ธํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•˜๊ณ , ์˜ต์…˜์œผ๋กœ nullable ๊ณผ updatable ์„ false ๋กœ ์„ค์ •ํ•˜๋ฉด JPA ๊ฐ€ ๋งคํ•‘ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹ , ์ผ๋Œ€๋‹ค ๊ตฌ์กฐ์˜ ์™ธ๋ž˜ํ‚ค ๊ตฌ์กฐ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
create table poll_item ( id bigint generated by default as identity, subject varchar(255), poll_id bigint not null, primary key (id) ) alter table poll_item add constraint FKs2aqtb9wm719gknvljgyf0ybp foreign key (poll_id) references poll
Java
๋ณต์‚ฌ
์œ„์˜ ์„ค์ •๋•๋ถ„์— @OneToMany ๋‹จ๋ฐฉํ–ฅ์ธ ์ผ๋Œ€๋‹ค ๊ตฌ์กฐ๋กœ ํ…Œ์ด๋ธ”์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ 2. ์ปฌ๋Ÿผ๋ช… ๋ณ€๊ฒฝ

์™ธ๋ž˜ ํ‚ค์™€ Map ์˜ key ๊ฐ€ ๋ณตํ•ฉํ‚ค๋กœ ์„ค์ •๋˜๋Š” ๊ฒƒ์€ ์˜๋„ํ•œ๋Œ€๋กœ ์ž˜ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ element collection ์˜ ์ปฌ๋Ÿผ ๋ช…์ด ์ œ๋Œ€๋กœ ๋“ค์–ด๊ฐ€์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
create table select_member ( poll_item_id bigint not null, values varchar(255), select_members_key bigint not null, primary key (poll_item_id, select_members_key) )
Java
๋ณต์‚ฌ
์ปฌ๋Ÿผ ๋ช…์„ ์„ค์ •ํ•˜๋ ค๋ฉด, Column ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ณ , key ๊ฐ’์— ์žˆ๋Š” ํƒ€์ž…์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” @MapKeyColumn ์„ ํ™œ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
@ElementCollection @CollectionTable( name = "select_member" ) @MapKeyColumn(name = "member_id") @Column(name = "description", nullable = false) private Map<Long, String> values = new HashMap<>();
Java
๋ณต์‚ฌ
์œ„์™€ ๊ฐ™์ด 2๊ฐœ์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•œ ๋’ค ๋‹ค์‹œ ์‹คํ–‰ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
create table select_member ( poll_item_id bigint not null, description varchar(255) not null, member_id bigint not null, primary key (poll_item_id, member_id) ) alter table select_member add constraint FK1jy0jmpad4ay1rxsw15olkpq7 foreign key (poll_item_id) references poll_item
Java
๋ณต์‚ฌ
์ปฌ๋Ÿผ ๋ช…์ด ์ž˜ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ 3. embedded ๊ฐ์ฒด ์ค‘๋ณต ์‚ฌ์šฉ

Poll ๊ฐ์ฒด๋Š” ๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„๋ฅผ ํ•˜๋ฉฐ ๊ธฐ์กด์— ์กด์žฌํ•˜๋˜ Team ๊ฐ์ฒด๋ฅผ ๊ฐ’ ๊ฐ์ฒด Code ํƒ€์ž…์˜ team code ๋ฅผ ๊ฐ€์ง„ ๊ฐ„์ ‘ ์ฐธ์กฐ ํ˜•ํƒœ๋กœ ๋ณ€๊ฒฝํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ €ํฌ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ƒ, team ์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋กœ team id ๋Œ€์‹  ๋žœ๋คํ•œ 8์ž๋ฆฌ์˜ unique ์ œ์•ฝ ์กฐ๊ฑด์ด ์กด์žฌํ•˜๋Š” team code ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ Poll ์—์„œ team ์˜ ์‹๋ณ„์ž๋กœ team id ๋Œ€์‹  team code ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํšจ์œจ์ ์ผ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.
@Entity public class Poll { @Embedded public Code teamCode; @Embedded public Code code; }
Java
๋ณต์‚ฌ
์—ฌ๊ธฐ์„œ code ๋Š” Poll ์—์„œ ์‹๋ณ„์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋žœ๋คํ•œ 8์ž๋ฆฌ ๊ฐ’์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ team code ์™€ code(poll cod) ๋ชจ๋‘ ๊ฐ’ ๊ฐ์ฒด์ธ Code ๋ฅผ ํ™œ์šฉํ•˜์˜€๊ณ , ์ž„๋ฒ ๋“œ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋กœ ์ธํ•ด ์ปฌ๋Ÿผ ๋ช…์˜ ์ค‘๋ณต์ด ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์œ„์˜ Poll ๊ฐ์ฒด๋งŒ ๋ณด์•˜์„ ๋•Œ๋Š” ๋ณ€์ˆ˜๋ช…์ด ๋‹ค๋ฅด๊ธฐ์— ์•„๋ฌด๋Ÿฐ ์ƒ๊ฐ์—†์ด ๋ฌธ์ œ์ ์„ ์ „ํ˜€ ํŒŒ์•…ํ•˜์ง€ ๋ชปํ–ˆ๋Š”๋ฐ, ์‚ฌ์‹ค ๋‹น์—ฐํ•œ ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค. @Embedded ํƒ€์ž…์€ ์•ž์„œ ์–ธ๊ธ‰๋“œ๋ ธ๋“ฏ์ด @Embedded ํƒ€์ž… ๋‚ด๋ถ€์˜ ํ•„๋“œ๋ฅผ ์ปฌ๋Ÿผ๋ช…์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ , ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ํ•„๋“œ๋Š” code ๋ผ๋Š” ๋ณ€์ˆ˜๋ช…์„ ๊ฐ€์กŒ๊ธฐ์—, JPA ์—์„œ๋Š” Poll ํ…Œ์ด๋ธ” ์ƒ์„ฑ์‹œ ์ปฌ๋Ÿผ๋ช… ์ค‘๋ณต ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜ํ•˜๊ฒŒ ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
@Column ์–ด๋…ธํ…Œ์ด์…˜ ๋˜ํ•œ ์ž„๋ฒ ๋“œ ํƒ€์ž… ๋‚ด๋ถ€ ํ•„๋“œ์— ์ ์šฉ๋˜๊ธฐ๋•Œ๋ฌธ์— Poll ๊ฐ์ฒด์—์„œ๋Š” ํ•ด๋‹น ํ•„๋“œ์—์„œ @Column ์œผ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
// ๋ถˆ๊ฐ€๋Šฅ!! ๊ฐ™์€ ์˜ˆ์™ธ ๋ฐœ์ƒ @Entity public class Poll { @Embedded @Column(name = "team_code") public Code teamCode; @Embedded @Column(name = "code") public Code code; }
Java
๋ณต์‚ฌ
โ€˜๋‘˜ ์ค‘ ํ•˜๋‚˜๋งŒ @Embedded ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” String ์„ ์‚ฌ์šฉํ• ๊นŒ,,โ€™ ๋ผ๋Š” ๋ถˆ์†ํ•œ ์ƒ๊ฐ์„ ์ž ๊น ํ•˜์˜€์ง€๋งŒ ๊ธฐ์ˆ ์ ์œผ๋กœ ํ•ด๊ฒฐํ•ด๋ณด๊ณ ์ž ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ปฌ๋Ÿผ์— ์ •๋ณด๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ JPA ์˜ ๊ธฐ๋Šฅ๋“ค์„ ์ฐพ์•„๋ณด๋‹ค๊ฐ€ JPA ์˜ ์–ด๋…ธํ…Œ์ด์…˜ ์ค‘ @AttributeOverride ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ฐœ๊ฒฌํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ ํ•„๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•˜๋ฉด ์œ„์˜ ๋ถˆ๊ฐ€๋Šฅ ์˜ˆ์‹œ์˜ @Column ์ฒ˜๋Ÿผ Poll ๊ฐ์ฒด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@Entity public class Poll { @Embedded @AttributeOverride(name = "code", column = @Column(name = "team_code")) public Code teamCode; @Embedded @AttributeOverride(name = "code", column = @Column(name = "code")) public Code code; }
Java
๋ณต์‚ฌ
์˜ต์…˜ ์ค‘ name ์€ ์ž„๋ฒ ๋“œ ํƒ€์ž… ๋‚ด๋ถ€ ๋ณ€์ˆ˜ ์ค‘ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•  ๋ณ€์ˆ˜๋ช…์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ณ , column ์˜ต์…˜์€ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ปฌ๋Ÿผ ๋ช…์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์žฌ์„ค๊ณ„ ์ ์šฉ ๊ฒฐ๊ณผ

์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ๋ถˆ๊ฐ€ํ”ผํ•˜๊ฒŒ ์กด์žฌํ–ˆ๋˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋„๋ฉ”์ธ ๊ฐ์ฒด๋กœ ์˜ฎ๊ฒจ ์ฝ”๋“œ์˜ ์‘์ง‘๋„๋ฅผ ๋†’์ด๊ณ , ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋•๋ถ„์— ์„œ๋น„์Šค ๊ณ„์ธต์˜ ์ฝ”๋“œ์˜ ์–‘๋„ ์ค„์–ด ํ•ต์‹ฌ ๋กœ์ง ํŒŒ์•…์— ๋”์šฑ ์œ ๋ฆฌํ•˜์—ฌ ์œ ์ง€, ๋ณด์ˆ˜ํ•˜๊ธฐ ์ˆ˜์›”ํ•œ ์ฝ”๋“œ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ธฐ์กด์—๋Š” ๋‹จ์ˆœํžˆ @Entity, @ManyToOne, Spring Data JPA ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜์˜€๋Š”๋ฐ, ์„ค๊ณ„ํ•œ ๋‚ด์šฉ์„ ์ ์šฉํ•˜๋Š” ๊ณผ์ •์—์„œ๋Š” @CollectionTable, @AttributeOverride๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ๋”ํ‹ฐ ์ฒดํ‚น์„ ์ด์šฉํ•œ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ๋Œ€์ ์œผ๋กœ DB ์— ๋œ ์ข…์†์ ์ธ ๊ฐ์ฒด์ง€ํ–ฅ์  ๊ตฌ์กฐ๋ฅผ ๊ฐ€์งˆ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ฌธ์ œ์ ์ด ๋‚จ์•„์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „ ๊ฒŒ์‹œ๊ธ€์—์„œ ์ฟผ๋ฆฌ์˜ ์„ฑ๋Šฅ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด @Query ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ JPQL ์„ ์ƒ์„ฑํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ join ์ฟผ๋ฆฌ๋ฅผ ์—†์• ๊ณ , fetch join๊ณผ default_batch_fetch_size ์˜ต์…˜ ๋“ฑ์„ ํ™œ์šฉํ•˜์—ฌ N+1 ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ˜„์žฌ๋Š” ๊ฒ€์ฆ ๋กœ์ง๊ณผ ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ์ฟผ๋ฆฌ๋Š” JPA ์˜ ๋”ํ‹ฐ ์ฒดํ‚น์— ๋งก๊ธฐ๋‹ค๋ณด๋‹ˆ ๋˜ ๋‹ค์‹œ N+1 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ๋„ ํ•˜๊ณ , ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ–ˆ๋˜ ์ฟผ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ๋„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ์ฟผ๋ฆฌ ํŠœ๋‹์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ๋” ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์žก์•˜์Šต๋‹ˆ๋‹ค. ์ด์— ๊ด€ํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.