๐Ÿš€ Growth/TIL

[TIL] 2026๋…„ 01์›” 05์ผ

devCloud 2026. 1. 5. 19:09
728x90

JPA ๋งคํ•‘ ์ •๋ณด๋Š” XML์ด๋‚˜ ์–ด๋…ธํ…Œ์ด์…˜ ์ค‘์— ์„ ํƒํ•ด์„œ ๊ธฐ์ˆ ํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿผ XML์€ ๋ฌด์—‡์ผ๊นŒ?

 

XML

XML(eXtensible Markup Language)์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌ์กฐํ™”ํ•˜๊ณ  ์ €์žฅํ•˜๋ฉฐ ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๋งˆํฌ์—… ์–ธ์–ด๋กœ, HTML๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ๋ฏธ๋ฆฌ ์ •์˜๋œ ํƒœ๊ทธ ์—†์ด ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ํƒœ๊ทธ๋ฅผ ์ •์˜ํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ์˜๋ฏธ์™€ ๊ตฌ์กฐ๋ฅผ ์„ค๋ช…ํ•œ๋‹ค.

 

์‚ฌ์šฉ ๋ฐฉ์‹

JPA์—์„œ XML๋กœ ๋งคํ•‘์„ ์“ฐ๋Š” ๋ฐฉ์‹์€ ํ‘œ์ค€์ ์œผ๋กœ orm.xml(JPA ORM ๋งคํ•‘ ํŒŒ์ผ) ์„ ๋‘๊ณ , ์ด๋ฅผ ์Šคํ”„๋ง ๋ถ€ํŠธ/JPA ์„ค์ •์— “๋งคํ•‘ ๋ฆฌ์†Œ์Šค”๋กœ ๋“ฑ๋กํ•˜๋Š” ํ˜•ํƒœ์ด๋‹ค. (์ฆ‰, ์–ด๋…ธํ…Œ์ด์…˜ ๋Œ€์‹  ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์„ “๋ฎ์–ด์“ฐ๋Š”” ์šฉ๋„๋กœ XML์„ ์“ด๋‹ค.)

 

1) orm.xml ํŒŒ์ผ์„ ์–ด๋””์— ๋‘๋‚˜์š”?

๊ฐ€์žฅ ํ”ํ•œ ๊ธฐ๋ณธ ์œ„์น˜๋Š” ์•„๋ž˜์ž…๋‹ˆ๋‹ค.

  • src/main/resources/META-INF/orm.xml

์Šคํ”„๋ง(JPA ์„ค์ •)์€ ๋ณ„๋„ ์ง€์ •์ด ์—†์œผ๋ฉด ํด๋ž˜์ŠคํŒจ์Šค์—์„œ ๊ธฐ๋ณธ META-INF/orm.xml์„ ์ฐพ์•„ ๋งคํ•‘ ๋ฆฌ์†Œ์Šค๋กœ ๋“ฑ๋กํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ orm.xml์˜ ์Šคํ‚ค๋งˆ(XSD)๋Š” Jakarta Persistence ORM ์Šคํ‚ค๋งˆ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. 

 

2) orm.xml์—๋Š” ๋ฌด์—‡์„ ์ ๋‚˜์š”?

orm.xml์—๋Š” “์–ด๋–ค ํด๋ž˜์Šค๊ฐ€ ์–ด๋–ค ํ…Œ์ด๋ธ”/์ปฌ๋Ÿผ๊ณผ ๋งคํ•‘๋˜๋Š”์ง€”, “ID๋Š” ๋ฌด์—‡์ธ์ง€”, “์—ฐ๊ด€๊ด€๊ณ„/์†์„ฑ ๋งคํ•‘” ๊ฐ™์€ ์—”ํ‹ฐํ‹ฐ ๋งคํ•‘ ์ •๋ณด๋ฅผ XML๋กœ ๊ธฐ์ˆ ํ•ฉ๋‹ˆ๋‹ค(์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ํ•˜๋˜ ๋‚ด์šฉ์„ XML ํƒœ๊ทธ๋กœ ์˜ฎ๊ธฐ๋Š” ํ˜•ํƒœ). 

 

๋˜ํ•œ ์ƒํ™ฉ์— ๋”ฐ๋ผ

  • ์–ด๋…ธํ…Œ์ด์…˜ + XML ํ˜ผ์šฉ(์ผ๋ถ€๋งŒ XML๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ) ๋˜๋Š”
  • XML๋งŒ ์‚ฌ์šฉ(์–ด๋…ธํ…Œ์ด์…˜ ๋ฌด์‹œ)
    ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ metadata-complete๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด “์ด XML์ด ์ „๋ถ€๋‹ค(์–ด๋…ธํ…Œ์ด์…˜์€ ๋ณด์ง€ ๋งˆ๋ผ)”๋ผ๋Š” ์˜๋ฏธ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. 

 

3) ์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ orm.xml์„ “์ฝ๊ฒŒ” ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ๋Š” ๋ณดํ†ต ์•„๋ž˜ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐฉ๋ฒ• A) application.yml(๋˜๋Š” properties)์— ๋งคํ•‘ ๋ฆฌ์†Œ์Šค ๋“ฑ๋ก

์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” spring.jpa.mapping-resources๋กœ persistence.xml์˜ <mapping-file>๊ณผ ๋™์ผํ•œ ์—ญํ• ์„ ํ•˜๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

spring:
  jpa:
    mapping-resources:
      - META-INF/orm.xml

 

๋ฐฉ๋ฒ• B) ๊ธฐ๋ณธ ์œ„์น˜(META-INF/orm.xml)์— ๋‘๊ณ  ์ž๋™ ํƒ์ง€์— ๋งก๊ธฐ๊ธฐ

๋ช…์‹œ ์„ค์ •์„ ์•ˆ ํ•ด๋„, ์Šคํ”„๋ง์˜ JPA ์„ค์ •์€ ๊ธฐ๋ณธ META-INF/orm.xml์„ ์ฐพ์•„ ๋“ฑ๋กํ•˜๋ ค๋Š” ๋™์ž‘์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ์— ๋”ฐ๋ผ ์ค‘๋ณต ๋กœ๋”ฉ/๋ฏธ๋กœ๋”ฉ ์ด์Šˆ๊ฐ€ ๋‚  ์ˆ˜ ์žˆ์–ด์„œ, ์šด์˜ ๊ด€์ ์—์„œ๋Š” ์œ„์˜ ๋ฐฉ๋ฒ• A์ฒ˜๋Ÿผ ๋ช…์‹œํ•˜๋Š” ๊ฑธ ๋” ๊ถŒํ•ฉ๋‹ˆ๋‹ค.

 

4) (์ฐธ๊ณ ) persistence.xml์„ ์“ฐ๋Š” ์ „ํ†ต์ ์ธ JPA ๋ฐฉ์‹์ด๋ผ๋ฉด

persistence.xml์„ ๋‘๋Š” ๊ตฌ์„ฑ(์ˆœ์ˆ˜ JPA ๋ถ€ํŠธ์ŠคํŠธ๋žฉ)์ด๋ผ๋ฉด, ๊ทธ ์•ˆ์— <mapping-file>๋กœ XML ๋งคํ•‘ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

5) ์–ด๋…ธํ…Œ์ด์…˜์ด๋ž‘ ๊ฐ™์ด ์“ฐ๋ฉด ์šฐ์„ ์ˆœ์œ„๋Š”?

์ผ๋ฐ˜์ ์œผ๋กœ ์–ด๋…ธํ…Œ์ด์…˜๊ณผ XML์„ ๊ฐ™์ด ์“ฐ๋ฉด ๋ณ‘ํ•ฉ๋˜๊ณ , ์ถฉ๋Œ ์‹œ์—๋Š” XML์ด ์šฐ์„ (์˜ค๋ฒ„๋ผ์ด๋“œ) ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ตฌ์„ฑ์ด ํ”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  metadata-complete๋ฅผ ์ผœ๋ฉด ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ฌด์‹œํ•˜๋Š” ์ชฝ์œผ๋กœ ๊ฐ‘๋‹ˆ๋‹ค.


๋„๋ฉ”์ธ ๋ชจ๋ธ

๋„๋ฉ”์ธ ๋ชจ๋ธ์€ ์„œ๋น„์Šค๊ฐ€ ๋‹ค๋ฃจ๋Š” ํ˜„์‹ค ์„ธ๊ณ„์˜ ๊ฐœ๋…(ํšŒ์›, ์ฃผ๋ฌธ, ๊ฒฐ์ œ ๊ฐ™์€ ๊ฒƒ๋“ค)์„ ์†Œํ”„ํŠธ์›จ์–ด ์•ˆ์—์„œ ๊ฐ์ฒด์™€ ๊ด€๊ณ„๋กœ ํ‘œํ˜„ํ•œ ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค. ์ด๋•Œ ์ค‘์š”ํ•œ ์ ์€ ๋‹จ์ˆœํžˆ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋งŒ ๋งŒ๋“œ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ๊ทธ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™๊ณผ ๋™์ž‘(ํ–‰๋™)๊นŒ์ง€ ํ•จ๊ป˜ ๋‹ด๋Š” “์—…๋ฌด ์ค‘์‹ฌ ๊ฐ์ฒด ๋ชจ๋ธ”์ด๋ผ๋Š” ๊ฒ๋‹ˆ๋‹ค.

 

๋„๋ฉ”์ธ ๋ชจ๋ธ ์˜ˆ์‹œ

  • ํšŒ์›๊ณผ ์ฃผ๋ฌธ์˜ ๊ด€๊ณ„: ํšŒ์›์€ ์—ฌ๋Ÿฌ ๋ฒˆ ์ฃผ๋ฌธํ•  ์ˆ˜ ์žˆ๋‹ค. (์ผ๋Œ€๋‹ค)
  • ์ฃผ๋ฌธ๊ณผ ์ƒํ’ˆ์˜ ๊ด€๊ณ„: ์ฃผ๋ฌธํ•  ๋•Œ ์—ฌ๋Ÿฌ ์ƒํ’ˆ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜ ๋Œ€๋กœ ๊ฐ™์€ ์ƒํ’ˆ๋„ ์—ฌ๋Ÿฌ ๋ฒˆ ์ฃผ๋ฌธ๋  ์ˆ˜ ์žˆ๋‹ค. ์ฃผ๋ฌธ์ƒํ’ˆ ์ด๋ผ๋Š” ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด์„œ ๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„๋ฅผ ์ผ๋‹ค๋Œ€, ๋‹ค๋Œ€์ผ ๊ด€๊ณ„๋กœ ํ’€์–ด๋ƒ„.


"๊ฐ์ฒด์ง€ํ–ฅ์Šค๋Ÿฝ์ง€ ์•Š๋‹ค"๋Š” ๋ฌด์Šจ ์˜๋ฏธ์ผ๊นŒ?

๊ฐ์ฒด ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ๊ฐ์ฒด(์ฐธ์กฐ)๋กœ ํ‘œํ˜„ํ•˜์ง€ ์•Š๊ณ  ์ˆซ์ž ID ๊ฐ™์€ ๊ฐ’์œผ๋กœ๋งŒ ๋‹ค๋ค„์„œ, ๋ชจ๋ธ์ด '๊ฐ์ฒด ํ˜‘๋ ฅ'์ด ์•„๋‹ˆ๋ผ '๊ฐ’ ์กฐ์ž‘' ์ค‘์‹ฌ์œผ๋กœ ํ˜๋Ÿฌ๊ฐ„๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. 

 

๊ฐ์ฒด์ง€ํ–ฅ์Šค๋Ÿฝ์ง€ ์•Š์€ ์ฝ”๋“œ ์˜ˆ์‹œ

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setTeamId(team.getId());
em.persist(member);
  • ๊ด€๊ณ„๋ฅผ '๊ฐ์ฒด ์ฐธ์กฐ'๊ฐ€ ์•„๋‹ˆ๋ผ '์™ธ๋ž˜ํ‚ค ๊ฐ’'์œผ๋กœ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.
    • ์ž๋ฐ”/๊ฐ์ฒด ๊ด€์ ์—์„œ "Member๋Š” Team์— ์†ํ•œ๋‹ค."๋Š” ๊ด€๊ณ„๋Š” ๋ณดํ†ต Member → Team ์ฐธ์กฐ(ํ•„๋“œ)๋กœ ํ‘œํ˜„ํ•˜๋Š” ๊ฒŒ ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. JPA๋„ ์ด๋Ÿฐ "๋‹จ์ผ ๊ฐ’ ์—ฐ๊ด€(association)"์„ @ManyToOne์œผ๋กœ ํ‘œํ˜„ํ•˜๋„๋ก ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, JPA๋Š” ์›๋ž˜ "์ฝ”๋“œ์—์„œ๋Š” ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ , DB์—๋Š” ๊ทธ ๊ฒฐ๊ณผ๋กœ FK๊ฐ€ ์ €์žฅ๋˜๊ฒŒ" ๋งŒ๋“œ๋Š” ORM์ž…๋‹ˆ๋‹ค.
  • ๋„๋ฉ”์ธ ๋ชจ๋ธ์ด DB ๊ตฌ์กฐ๋ฅผ ๊ทธ๋Œ€๋กœ ๋Œ์–ด์•ˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 
    • teamId๋Š” ์‚ฌ์‹ค์ƒ DB์˜ FK ํ‘œํ˜„์ธ๋ฐ, ์ด๊ฑธ ์—”ํ‹ฐํ‹ฐ์— ์ง์ ‘ ๋“ค๊ณ  ์žˆ์œผ๋ฉด ๋ชจ๋ธ์ด "๊ฐ์ฒด ๊ด€๊ณ„"๋ณด๋‹ค "ํ…Œ์ด๋ธ” ์กฐ์ธ/ํ‚ค ๊ฐ’" ์ค‘์‹ฌ์ด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ฒฐ๊ตญ ์„œ๋น„์Šค ์ฝ”๋“œ์—์„œ ๋งค๋ฒˆ teamId๋กœ ๋‹ค์‹œ ์กฐํšŒํ•ด์„œ ๋ถ™์ด๋Š” ์‹์ด ๋˜๊ณ , ๊ฐ์ฒด๊ฐ€ ๊ฐ์ฒด๋‹ต๊ฒŒ ํ˜‘๋ ฅํ•˜๊ธฐ๋ณด๋‹ค ์ ˆ์ฐพ๊ฑฐ์œผ๋กœ ํ˜๋Ÿฌ๊ฐ€๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. (JPA๊ฐ€ ์ œ๊ณตํ•˜๋ ค๋Š” ์ด์ ์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.)
  • ๋ถˆ์ผ์น˜/๋ฌด๊ฒฐ์„ฑ ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.
    • teamId๋Š” ์ˆซ์ž์ผ ๋ฟ์ด๋ผ, "์กด์žฌํ•˜์ง€ ์•Š๋Š” ํŒ€ ID"๋ฅผ ๋„ฃ์–ด๋„ ๊ฐ์ฒด ์ž์ฒด๋Š” ๋ง‰์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด "Team ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐ"ํ•˜๋ฉด ๊ด€๊ณ„๊ฐ€ ๋” ๋ช…ํ™•ํ•ด์ง€๊ณ , ๋ณ€๊ฒฝ ์ง€์ ๋„ ์ค„์–ด ๋ชจ๋ธ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. (ํŠนํžˆ ์–‘๋ฐฉํ–ฅ์ด๋ฉด ํ•œ์ชฝ๋งŒ ๋ฐ”๊ฟ”์„œ ๊ด€๊ณ„๊ฐ€ ๊นจ์ง€๋Š” ๋ฌธ์ œ๋ฅผ ์ค„์ด๋ ค๋ฉด, ๊ด€๊ณ„ ๋ณ€๊ฒฝ์„ ํ•œ ๋ฉ”์„œ๋“œ๋กœ ์บก์Аํ™”ํ•˜๋Š” ์‹์ด ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.)

๊ทธ๋ž˜์„œ JPA/ORM ๊ด€์ ์—์„œ “๊ฐ์ฒด์ง€ํ–ฅ์Šค๋Ÿฝ๊ฒŒ”๋Š” ๋ณดํ†ต Member๊ฐ€ teamId๋ฅผ ๊ฐ–๋Š” ๋Œ€์‹  Team์„ ์ฐธ์กฐํ•˜๊ฒŒ ํ•˜๊ณ , JPA๊ฐ€ ๊ทธ ์ฐธ์กฐ๋ฅผ ์™ธ๋ž˜ํ‚ค๋กœ ๋งคํ•‘ํ•˜๊ฒŒ ๋‘๋Š” ๊ฑธ ๋งํ•ฉ๋‹ˆ๋‹ค. Hibernate ๋ฌธ์„œ์—์„œ๋„ FK ๊ด€๊ณ„๋Š” @ManyToOne ๊ฐ™์€ ํ‘œ์ค€ ์—ฐ๊ด€ ๋งคํ•‘์„ ์šฐ์„ ํ•˜๋ผ๊ณ  ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค.

 

์ฐธ๊ณ ๋กœ, DTO(์š”์ฒญ/์‘๋‹ต)๋‚˜ API ๊ฒฝ๊ณ„์—์„œ๋Š” ID๋กœ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ฒŒ ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ “์—”ํ‹ฐํ‹ฐ/๋„๋ฉ”์ธ ๋ชจ๋ธ ๋‚ด๋ถ€”์—์„œ๋Š” ๊ด€๊ณ„๋ฅผ ๊ฐ์ฒด ์ฐธ์กฐ๋กœ ๋ชจ๋ธ๋งํ•˜๋Š” ์ชฝ์ด ๋ณดํ†ต ๋” ๊ฐ์ฒด์ง€ํ–ฅ์ ์ด๋ผ๊ณ  ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค.


์ฝ”๋“œ ๋ถ„์„(100L)

Team newTeam = em.find(Team.class, 100L);
  • 100L์€ ์กฐํšŒํ•˜๋ ค๋Š” Team ์—”ํ‹ฐํ‹ฐ์˜ "๊ธฐ๋ณธ ํ‚ค(PK)"์ž…๋‹ˆ๋‹ค. ์ฆ‰, @Id๋กœ ์ง€์ •๋œ ๊ฐ’์ด 100์ธ ํŒ€์„ ์ฐพ์•„์˜ค๊ฒ ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ๋’ค์˜ L์€ ์ž๋ฐ”์—์„œ "long ํƒ€์ž… ๋ฆฌํ„ฐ๋Ÿด" ํ‘œ์‹œ๋ผ์„œ, 100L์€ long(๋ณดํ†ต Long์œผ๋กœ ์‚ฌ์šฉ) ๊ฐ’ 100์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • ์ฐธ๊ณ ๋กœ find()๋Š” ๊ธฐ๋ณธ ํ‚ค๋กœ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ฐพ๋Š” ๋ฉ”์„œ๋“œ์ด๊ณ , ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์—†์œผ๋ฉด ๋ณดํ†ต null์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
728x90

'๐Ÿš€ Growth > TIL' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[TIL] ๊ฐœ๋ฐœ ๊ธฐ๋ณธ ์šฉ์–ด  (0) 2026.04.01
[TIL] 2026๋…„ 01์›” 07์ผ  (0) 2026.01.07
[์Šคํ”„๋ง] 2025-07-02  (1) 2025.07.02
[TIL] 2024๋…„ 11์›” 14์ผ  (1) 2024.11.15
[TIL] 2024๋…„ 11์›” 11์ผ  (1) 2024.11.12