๐Ÿ“Š entity์—์„œ dto๋กœ: ์„ธ ๊ฐ€์ง€ ๋งคํ•‘ ๋ฐฉ์‹์˜ ์„ฑ๋Šฅ ๋น„๊ต

ยท3 min readยท3ยท
๐Ÿ“Š Entity์—์„œ DTO๋กœ: ์„ธ ๊ฐ€์ง€ ๋งคํ•‘ ๋ฐฉ์‹์˜ ์„ฑ๋Šฅ ๋น„๊ต

๐Ÿ“Š Entity์—์„œ DTO๋กœ: ์„ธ ๊ฐ€์ง€ ๋งคํ•‘ ๋ฐฉ์‹์˜ ์„ฑ๋Šฅ ๋น„๊ต

๐ŸŽฏ ๋“ค์–ด๊ฐ€๋ฉฐ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋…ธ์ถœํ•  ๋•Œ DTO๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋งŽ์€ ์žฅ์ ์ด ์žˆ์–ด ๊ฐ•๋ ฅํžˆ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ๋…ธ์ถœ๋˜๋Š” ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ๋ถ€ํ„ฐ ์„ฑ๋Šฅ ๋ฐ ๋ณด์•ˆ ๋ฌธ์ œ๊นŒ์ง€, DTO๋Š” ๋ชจ๋“  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ DTO์—๋Š” ์ค‘์š”ํ•œ ๋‹จ์ ์ด ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค โš ๏ธ: ํ•ญ์ƒ ์—”ํ‹ฐํ‹ฐ์™€ DTO ๊ฐ„์˜ ๋ณ€ํ™˜์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ถ”๊ฐ€์ ์ธ ๋ณต์žก์„ฑ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

๐Ÿ’ก ์ด ๊ธ€์—์„œ๋Š” Entity๋ฅผ DTO๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ณ , ๊ทธ ์ค‘ ์–ด๋–ค ๊ฒƒ์ด ๊ฐ€์žฅ ์„ฑ๋Šฅ์ด ์ข‹์€์ง€ ์ฐพ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿ› ๏ธ ๋งคํ•‘ ๊ธฐ๋ฒ•

์ด๋ฒˆ ๊ธ€์—์„œ ๋น„๊ตํ•  ๋งคํ•‘ ์˜ต์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

1๏ธโƒฃ Manual mapping (์ˆ˜๋™ ๋งคํ•‘)

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฒ•์œผ๋กœ, ๊ฐœ๋ฐœ์ž๊ฐ€ Entity์˜ ํ•„๋“œ๋ฅผ DTO๋กœ ์ˆ˜๋™์œผ๋กœ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ MapStruct

์ˆ˜๋™ ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ์ž๋™์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋ฉฐ, ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•„๋“œ๋ฅผ ์ˆ˜๋™์œผ๋กœ ๋งคํ•‘ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

3๏ธโƒฃ JPQL

JPQL์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฟผ๋ฆฌ์—์„œ ์ง์ ‘ Entity๋ฅผ DTO๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ์ ‘๊ทผ ๋ฐฉ์‹์—๋Š” ์žฅ๋‹จ์ ์ด ์žˆ์œผ๋ฉฐ, ์–ด๋–ค ๊ฒƒ์„ ์‚ฌ์šฉํ• ์ง€๋Š” ๊ฐœ๋ฐœ์˜ ๋ณต์žก์„ฑ์ด๋‚˜ ์•„ํ‚คํ…์ฒ˜ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿค”


โš–๏ธ ๋น„๊ต ์‹คํ—˜

์ด์ œ ๋‘ ๊ฐ€์ง€ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ธ ๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:

  • ๊ฐ„๋‹จํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค
  • ๋ณต์žกํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค

๐Ÿ“š ๊ฐ„๋‹จํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค

์‹คํ—˜์€ ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ์™€ ๊ด€๊ณ„๊ฐ€ ์—†๋Š” ๊ฐ„๋‹จํ•œ ์—”ํ‹ฐํ‹ฐ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์—๋Š” 1000๊ฐœ์˜ ์ฑ…์ด ์‚ฝ์ž…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Book ์—”ํ‹ฐํ‹ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•„๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค:

  • id (๊ณ ์œ  ์‹๋ณ„์ž)
  • name (์ฑ… ์ด๋ฆ„)
  • author (์ €์ž)
  • releaseDate (์ถœํŒ์ผ)
  • numberOfPages (ํŽ˜์ด์ง€ ์ˆ˜)
  • language (์–ธ์–ด)

BookDTO๋Š” ์—”ํ‹ฐํ‹ฐ์™€ ๋™์ผํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

์„ธ ๊ฐ€์ง€ ๋งคํ•‘ ๋ฐฉ์‹ ๋ชจ๋‘ BookDTO ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์‹œ๋‚˜๋ฆฌ์˜ค๋งˆ๋‹ค 100๋ฒˆ์˜ ์š”์ฒญ์„ ์‹คํ–‰ํ–ˆ๊ณ , ๋‹ค์Œ์€ ๊ฐ๊ฐ์˜ ํ‰๊ท  ์‹คํ–‰ ์‹œ๊ฐ„(ms)์ž…๋‹ˆ๋‹ค:

๐Ÿ“ˆ ์„ฑ๋Šฅ ๊ฒฐ๊ณผ:

  • โœ‹ Manual ๋ฐฉ์‹: 11ms
  • ๐Ÿ”ง MapStruct ๋ฐฉ์‹: 10ms
  • ๐Ÿ“ JPQL ๋ฐฉ์‹: 8ms

๋ณด์‹œ๋‹ค์‹œํ”ผ, ์„ธ ๋ฐฉ์‹ ๊ฐ„์˜ ์ฐจ์ด๋Š” ๋ฏธ๋ฏธํ•ฉ๋‹ˆ๋‹ค. JPQL ๋ฒ„์ „์ด ์•ฝ๊ฐ„ ๋” ๋น ๋ฅด์ง€๋งŒ ํฐ ์ฐจ์ด๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๐Ÿ”— ๋ณต์žกํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค

์ด์ œ ์—”ํ‹ฐํ‹ฐ์— @ManyToOne ๊ด€๊ณ„๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์กฐ๊ธˆ ๋” ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ Book์€ ์ด์ œ Publisher๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Publisher ์—”ํ‹ฐํ‹ฐ ํ•„๋“œ:

  • id (๊ณ ์œ  ์‹๋ณ„์ž)
  • name (์ถœํŒ์‚ฌ ์ด๋ฆ„)
  • since (์„ค๋ฆฝ์ผ)
  • address (์ฃผ์†Œ)
  • country (๊ตญ๊ฐ€)

BookDTO๋„ ์ด์ œ PublisherDTO๋ฅผ ํฌํ•จํ•˜๋„๋ก ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

100๋ฒˆ์˜ ์š”์ฒญ์„ ๋‹ค์‹œ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ:

๐Ÿ“ˆ ์„ฑ๋Šฅ ๊ฒฐ๊ณผ:

  • โœ‹ Manual ๋ฐฉ์‹: 472ms ๐Ÿ˜ฑ
  • ๐Ÿ”ง MapStruct ๋ฐฉ์‹: 494ms ๐Ÿ˜ฑ
  • ๐Ÿ“ JPQL ๋ฐฉ์‹: 19ms โšก

์ด๋ฒˆ์—๋Š” ์ฐจ์ด๊ฐ€ ํ™•์—ฐํ•ฉ๋‹ˆ๋‹ค! JPQL ์˜ต์…˜์ด ๋‹ค๋ฅธ ๋‘ ์˜ต์…˜๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ๋ณด์˜€์Šต๋‹ˆ๋‹ค. Manual๊ณผ MapStruct๋Š” ๋น„์Šทํ•œ ์„ฑ๋Šฅ์„ ๋ณด์˜€์ง€๋งŒ... ์ฐจ์ด๊ฐ€ ๋„ˆ๋ฌด ํฌ์ง€ ์•Š๋‚˜์š”? ๐Ÿค” ์ข€ ๋” ๋ถ„์„ํ•ด๋ด…์‹œ๋‹ค!

๐Ÿ› N+1 ๋ฌธ์ œ ๋ฐœ๊ฒฌ!

Manual๊ณผ MapStruct ๋ฒ„์ „ ๋ชจ๋‘ JpaRepository์˜ findAll() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ publisher์˜ fetch ํƒ€์ž…์ด FetchType.LAZY๋กœ ์„ค์ •๋˜์–ด ์žˆ์–ด์„œ, ์—ฌ๊ธฐ์— N+1 ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค! ๐Ÿ˜ต

์ด๋Š” ๊ฐ fetch๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— 1001๋ฒˆ์˜ select๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค:

  • ๐Ÿ“– 1๋ฒˆ: ๋ชจ๋“  ์ฑ…์„ ๊ฐ€์ ธ์˜ค๋Š” select
  • ๐Ÿ“š 1000๋ฒˆ: ๊ฐ ์ฑ…์˜ ์ถœํŒ์‚ฌ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” select (์ฑ…์ด 1000๊ฐœ์˜€์œผ๋ฏ€๋กœ)

๐Ÿ› ๏ธ N+1 ๋ฌธ์ œ ํ•ด๊ฒฐ

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด @Query์™€ JOIN FETCH๋ฅผ ์‚ฌ์šฉํ•œ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋กœ ๊ต์ฒดํ–ˆ์Šต๋‹ˆ๋‹ค:

@Query("SELECT b FROM Book b JOIN FETCH b.publisher")
List<Book> findAllWithPublisher();

์ด ๋ณ€๊ฒฝ ํ›„์˜ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค! ๐ŸŽ‰

๐Ÿ“ˆ ์ตœ์ข… ์„ฑ๋Šฅ ๊ฒฐ๊ณผ:

  • โœ‹ Manual ๋ฐฉ์‹: 24ms โœจ
  • ๐Ÿ”ง MapStruct ๋ฐฉ์‹: 23ms โœจ
  • ๐Ÿ“ JPQL ๋ฐฉ์‹: 19ms โšก

Manual๊ณผ MapStruct ๋ฒ„์ „์˜ ์‹คํ–‰ ์‹œ๊ฐ„์ด ์—„์ฒญ๋‚˜๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๊ฒฐ๊ณผ๋Š” ๊ฐ„๋‹จํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์–ป์€ ๊ฒƒ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. JPQL์ด ๋‹ค์‹œ ์กฐ๊ธˆ ๋” ๋น ๋ฅด์ง€๋งŒ, ํฐ ์ฐจ์ด๋Š” ์—†์Šต๋‹ˆ๋‹ค.


๐Ÿ’ก ๊ฒฐ๋ก 

์„œ๋กœ ๋‹ค๋ฅธ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„ ๋‘ ๊ฐ€์ง€ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์‹คํ—˜์„ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ, Entity์—์„œ DTO๋กœ์˜ ์„ธ ๊ฐ€์ง€ ๋งคํ•‘ ์œ ํ˜• ๊ฐ„์— ํฐ ์ฐจ์ด๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ด ๋ฐํ˜€์กŒ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋‘ ์‹œ๋‚˜๋ฆฌ์˜ค ๋ชจ๋‘์—์„œ JPQL ์†”๋ฃจ์…˜์ด ๊ฐ€์žฅ ์šฐ์ˆ˜ํ–ˆ๊ณ , ๊ทธ ๋‹ค์Œ์ด MapStruct, ๋งˆ์ง€๋ง‰์œผ๋กœ Manual ์†”๋ฃจ์…˜์ด์—ˆ์Šต๋‹ˆ๋‹ค ๐Ÿ†

์„ฑ๋Šฅ์€ ๋น„์Šทํ•˜์ง€๋งŒ, ์–ด๋–ค ์†”๋ฃจ์…˜๋„ ๋ณดํŽธ์ ์œผ๋กœ ์ด์ƒ์ ์ด์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์— ๋”ฐ๋ผ ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค ๋” ์ž˜ ๋งž์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์€ ์„ ํ˜ธ๋„๋‚˜ ํŠน์ • ์š”๊ตฌ์‚ฌํ•ญ์˜ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐ŸŽฏ


โœ๏ธ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!


๐Ÿ“Œ ์ถœ์ฒ˜

์›๋ฌธ: Entity to DTO: A Performance Comparison of Three Mapping Approaches

์ €์ž: Flavius Zichil

๋ฐœํ–‰: Level Up Coding (2025๋…„ 9์›” 28์ผ)