[Sprint Mission6]

1. ํ”„๋กœ์ ํŠธ ๋งˆ์ผ์Šคํ†ค

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ™˜๊ฒฝ ์„ค์ • ๋ฐ ๋ชจ๋ธ๋ง
  • Spring Data JPA ํ™˜๊ฒฝ ์ ์šฉ
  • Entity ์—ฐ๊ด€ ๊ด€๊ณ„ ๋งคํ•‘
  • ๋ ˆํฌ์ง€ํ† ๋ฆฌ์™€ ์„œ๋น„์Šค ๊ณ„์ธต์— JPA ์ ์šฉ
  • Transaction ์ฒ˜๋ฆฌ
  • ํŽ˜์ด์ง€๋„ค์ด์…˜๊ณผ ์ •๋ ฌ
  • DTO์˜ ์ ๊ทน์ ์ธ ๋„์ž…๊ณผ MapStruct์˜ ํ™œ์šฉ
  • BinaryContent ์ €์žฅ ๋กœ์ง ๊ณ ๋„ํ™”
    • ๋ฉ”ํƒ€์ •๋ณด์™€ ๋ฐ”์ด๋„ˆ๋ฆฌ ์ •๋ณด ๋ถ„๋ฆฌ
  • N+1 ๋ฌธ์ œ ํ•ด๊ฒฐ

2. ๊ธฐ๋ณธ ์š”๊ตฌ์‚ฌํ•ญ

2-1. API ๋ช…์„ธ

โš ๏ธ ํ”„๋ก ํŠธ์—”๋“œ ์†Œ์Šค ์ฝ”๋“œ๋Š” ์ฐธ๊ณ ์šฉ์œผ๋กœ๋งŒ ํ™œ์šฉํ•˜์„ธ์š”. ์ˆ˜์ •ํ•˜์—ฌ ํ™œ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ด์–ด์ง€๋Š” ์š”๊ตฌ์‚ฌํ•ญ ๋˜๋Š” ๋ฏธ์…˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ์–ด๋ ค์›€์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


2-2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

  • ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜์„ธ์š”.
    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค:ย discodeit
    • ์œ ์ €:ย discodeit_user
    • ํŒจ์Šค์›Œ๋“œ:ย notion ์ฐธ๊ณ 
  • ERD๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ DDL์„ ์ž‘์„ฑํ•˜๊ณ , ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜์„ธ์š”.
    • ์ž‘์„ฑํ•œ DDL ํŒŒ์ผ์€ /src/main/resources/schema.sql ๊ฒฝ๋กœ์— ํฌํ•จํ•˜์„ธ์š”.

    • PK: Primary Key
    • UK: Unique Key
    • NN: Not Null
    • FK: Foreign Key
      • ON DELETE CASCADE: ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ ์‚ญ์ œ ์‹œ ๊ฐ™์ด ์‚ญ์ œ
      • ON DELETE SET NULL: ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ ์‚ญ์ œ ์‹œ NULL๋กœ ๋ณ€๊ฒฝ


2-3. Spring Data JPA ์ ์šฉํ•˜๊ธฐ

  • Spring Data JPA์™€ PostgreSQL์„ ์œ„ํ•œ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.
  • ์•ž์„œ ๊ตฌ์„ฑํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ •๊ฐ’์„ย application.yamlย ํŒŒ์ผ์— ์ž‘์„ฑํ•˜์„ธ์š”.
  • ๋””๋ฒ„๊น…์„ ์œ„ํ•ด SQL ๋กœ๊ทธ์™€ ๊ด€๋ จ๋œ ์„ค์ •๊ฐ’์„ย application.yamlย ํŒŒ์ผ์— ์ž‘์„ฑํ•˜์„ธ์š”.


2-4. ์—”ํ‹ฐํ‹ฐ ์ •์˜ํ•˜๊ธฐ

  • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ฐธ๊ณ ํ•ด ๋„๋ฉ”์ธ ๋ชจ๋ธ์˜ ๊ณตํ†ต ์†์„ฑ์„ ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ์ •์˜ํ•˜๊ณ  ์ƒ์† ๊ด€๊ณ„๋ฅผ ๊ตฌํ˜„ํ•˜์„ธ์š”.
    • ์ด๋•Œ Serializable ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค.
    • ํŒจํ‚ค์ง€๋ช…: com.sprint.mission.discodeit.entity.base
    • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

  • JPA์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•ด createdAt, updatedAt ์†์„ฑ์ด ์ž๋™์œผ๋กœ ์„ค์ •๋˜๋„๋ก ๊ตฌํ˜„ํ•˜์„ธ์š”.
    • @CreatedDate,ย @LastModifiedDate
  • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ฐธ๊ณ ํ•ด ํด๋ž˜์Šค ์ฐธ์กฐ ๊ด€๊ณ„๋ฅผ ์ˆ˜์ •ํ•˜์„ธ์š”. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ƒ์„ฑ์ž, update ๋ฉ”์†Œ๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ, ์•„์ง JPA Entity์™€ ๊ด€๋ จ๋œ ์–ด๋…ธํ…Œ์ด์…˜์€ ์ž‘์„ฑํ•˜์ง€ ๋งˆ์„ธ์š”.
    • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

    • ํ™”์‚ดํ‘œ์˜ ๋ฐฉํ–ฅ๊ณผ ํ™”์‚ดํ‘œ ์œ ๋ฌด์— ์œ ์˜ํ•˜์„ธ์š”.

  • ERD์™€ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ํ† ๋Œ€๋กœ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ ์ •๋ณด๋ฅผ ํ‘œ๋กœ ์ •๋ฆฌํ•ด๋ณด์„ธ์š”.(์ด ๋‚ด์šฉ์€ PR์— ์ฒจ๋ถ€ํ•ด์ฃผ์„ธ์š”.)
    • ์˜ˆ์‹œ

      ์—”ํ‹ฐํ‹ฐ ๊ด€๊ณ„ ๋‹ค์ค‘์„ฑ ๋ฐฉํ–ฅ์„ฑ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ
      A:B 1:N Bโ†’A ๋‹จ๋ฐฉํ–ฅ ๋ถ€๋ชจ: A, ์ž์‹: B B
      ? ? ? ? ?
      ? ? ? ? ?
  • JPA ์ฃผ์š” ์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•ด ERD, ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ ์ •๋ณด๋ฅผ ๋„๋ฉ”์ธ ๋ชจ๋ธ์— ๋ฐ˜์˜ํ•ด๋ณด์„ธ์š”.
    • @Entity,ย @Table
    • @Column,ย @Enumerated
    • @OneToMany,ย @OneToOne,ย @ManyToOne
    • @JoinColumn,ย @JoinTable
  • ERD์˜ ์™ธ๋ž˜ํ‚ค ์ œ์•ฝ ์กฐ๊ฑด๊ณผ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ ์ •๋ณด์˜ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๋ฅผ ๊ณ ๋ คํ•ด ์˜์†์„ฑ ์ „์ด์™€ ๊ณ ์•„ ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•˜์„ธ์š”.
    • cascade,ย orphanRemoval


2-5. ๋ ˆํฌ์ง€ํ† ๋ฆฌ์™€ ์„œ๋น„์Šค์— JPA ๋„์ž…ํ•˜๊ธฐ

  • ๊ธฐ์กด์˜ Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ JPARepository๋กœ ์ •์˜ํ•˜๊ณ  ์ฟผ๋ฆฌ๋ฉ”์†Œ๋“œ๋กœ ๋Œ€์ฒดํ•˜์„ธ์š”.
    • FileRepository์™€ JCFRepository ๊ตฌํ˜„์ฒด๋Š” ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ํŠน์ง•์— ๋งž์ถ”์–ด ์„œ๋น„์Šค ๋ ˆ์ด์–ด๋ฅผ ์ˆ˜์ •ํ•ด๋ณด์„ธ์š”.
    • ํžŒํŠธ:ย ํŠธ๋žœ์žญ์…˜,ย ์˜์†์„ฑ ์ „์ด,ย ๋ณ€๊ฒฝ ๊ฐ์ง€,ย ์ง€์—ฐ๋กœ๋”ฉ


2-6. DTO ์ ๊ทน ๋„์ž…ํ•˜๊ธฐ

  • Entity๋ฅผ Controller ๊นŒ์ง€ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœํ–ˆ์„ ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ ์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด์„ธ์š”. DTO๋ฅผ ์ ๊ทน ๋„์ž…ํ–ˆ์„ ๋•Œ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง€์ง€๋งŒ, ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์–ด๋–ค ์ด์ ์ด ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์„๊ฑฐ์—์š”.(์ด ๋‚ด์šฉ์€ PR์— ์ฒจ๋ถ€ํ•ด์ฃผ์„ธ์š”.)
    • ํžŒํŠธ
      • Entity์™€ API์˜ ๊ฒฐํ•ฉ
      • ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์„ฑ๋Šฅ์„ ๊ณ ๋ คํ•ด OSIV๋ฅผ false๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋Œ€๋ถ€๋ถ„
      • ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„ ์‹œ ์ˆœํ™˜ ์ฐธ์กฐ
      • ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ
  • ๋‹ค์Œ์˜ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ฐธ๊ณ ํ•˜์—ฌ DTO๋ฅผ ์ •์˜ํ•˜์„ธ์š”.

  • Entity๋ฅผ DTO๋กœ ๋งคํ•‘ํ•˜๋Š” ๋กœ์ง์„ ์ฑ…์ž„์ง€๋Š” Mapper ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•ด ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์ค„์—ฌ๋ณด์„ธ์š”.
    • ํŒจํ‚ค์ง€๋ช…:ย com.sprint.mission.discodeit.mapper


2-7. BinaryContent ์ €์žฅ ๋กœ์ง ๊ณ ๋„ํ™”

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ด๋ฏธ์ง€์™€ ๊ฐ™์€ ํŒŒ์ผ์„ ์ €์žฅํ•˜๋ฉด ์„ฑ๋Šฅ ์ƒ ๋ถˆ๋ฆฌํ•œ ์ ์ด ๋งŽ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋Š” ๋ณ„๋„์˜ ๊ณต๊ฐ„์— ์ €์žฅํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ฉ”ํƒ€ ์ •๋ณด(ํŒŒ์ผ๋ช…, ํฌ๊ธฐ, ์œ ํ˜• ๋“ฑ)๋งŒ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  • BinaryContent ์—”ํ‹ฐํ‹ฐ๋Š” ํŒŒ์ผ์˜ ๋ฉ”ํƒ€ ์ •๋ณด(fileName, size, contentType)๋งŒ ํ‘œํ˜„ํ•˜๋„๋ก bytes ์†์„ฑ์„ ์ œ๊ฑฐํ•˜์„ธ์š”.
  • BinaryContent์˜ byte[] ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ๋‹ด๋‹นํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„ค๊ณ„ํ•˜์„ธ์š”. ์ €์žฅ ๋งค์ฒด์˜ ํ™•์žฅ์„ฑ(๋กœ์ปฌ ์ €์žฅ์†Œ, ์›๊ฒฉ ์ €์žฅ์†Œ)์„ ๊ณ ๋ คํ•ด ์ธํ„ฐํŽ˜์ด์Šค๋ถ€ํ„ฐ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค.
    • ํŒจํ‚ค์ง€๋ช…: com.sprint.mission.discodeit.storage
    • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

    • BinaryContentStorage
      • ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ์˜ ์ €์žฅ/๋กœ๋“œ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
      • UUID put(UUID, byte[])
        • UUID ํ‚ค ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœย byte[]ย ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
        • UUID๋Š” BinaryContent์˜ Id ์ž…๋‹ˆ๋‹ค.
      • InputStream get(UUID)
        • ํ‚ค ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœย byte[]ย ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด InputStream ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
        • UUID๋Š” BinaryContent์˜ Id ์ž…๋‹ˆ๋‹ค.
      • ResponseEntity<?> download(BinaryContentDto)
        • HTTP API๋กœ ๋‹ค์šด๋กœ๋“œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
        • BinaryContentDto ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋Š” ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋น„์Šค ๋ ˆ์ด์–ด์—์„œ ๊ธฐ์กด์— BinaryContent๋ฅผ ์ €์žฅํ•˜๋˜ ๋กœ์ง์„ BinaryContentStorage๋ฅผ ํ™œ์šฉํ•˜๋„๋ก ๋ฆฌํŒฉํ† ๋งํ•˜์„ธ์š”.
  • BinaryContentController์— ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” API๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , BinaryContentStorage์— ๋กœ์ง์„ ์œ„์ž„ํ•˜์„ธ์š”.
    • ์—”๋“œํฌ์ธํŠธ: GET /api/binaryContents/{binaryContentId}/download
    • ์š”์ฒญ
      • ๊ฐ’: BinaryContentId
      • ๋ฐฉ์‹: Query Parameter
    • ์‘๋‹ต: ResponseEntity<?>
    • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

  • ๋กœ์ปฌ ๋””์Šคํฌ ์ €์žฅ ๋ฐฉ์‹์œผ๋กœ BinaryContentStorage ๊ตฌํ˜„์ฒด๋ฅผ ๊ตฌํ˜„ํ•˜์„ธ์š”.
    • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

  • discodeit.storage.type ๊ฐ’์ด local ์ธ ๊ฒฝ์šฐ์—๋งŒ Bean์œผ๋กœ ๋“ฑ๋ก๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • Path root
      • ๋กœ์ปฌ ๋””์Šคํฌ์˜ ๋ฃจํŠธ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.
      • discodeit.storage.local.root-pathย ์„ค์ •๊ฐ’์„ ์ •์˜ํ•˜๊ณ , ์ด ๊ฐ’์„ ํ†ตํ•ด ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.
    • void init()
      • ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
      • Bean์ด ์ƒ์„ฑ๋˜๋ฉด ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
    • Path resolvePath(UUID)
      • ํŒŒ์ผ์˜ ์‹ค์ œ ์ €์žฅ ์œ„์น˜์— ๋Œ€ํ•œ ๊ทœ์น™์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
        • ํŒŒ์ผ ์ €์žฅ ์œ„์น˜ ๊ทœ์น™ ์˜ˆ์‹œ:ย {root}/{UUID}
      • put,ย getย ๋ฉ”์†Œ๋“œ์—์„œ ํ˜ธ์ถœํ•ด ์ผ๊ด€๋œ ํŒŒ์ผ ๊ฒฝ๋กœ ๊ทœ์น™์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
    • ResponseEntity<Resource> donwload(BinaryContentDto)
      • getย ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํŒŒ์ผ์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
      • BinaryContentDto์™€ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•ดย ResponseEntity<Resource>ย ์‘๋‹ต์„ ์ƒ์„ฑ ํ›„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.


2-8. ํŽ˜์ด์ง•๊ณผ ์ •๋ ฌ

  • ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ๋•Œ ๋‹ค์Œ์˜ ์กฐ๊ฑด์— ๋”ฐ๋ผ ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด๋ณด์„ธ์š”.
    • 50๊ฐœ์”ฉ ์ตœ๊ทผ ๋ฉ”์‹œ์ง€ ์ˆœ์œผ๋กœ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๋ฉ”์‹œ์ง€๊ฐ€ ๋ช‡๊ฐœ์ธ์ง€ ์•Œ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.
  • ์ผ๊ด€๋œ ํŽ˜์ด์ง€๋„ค์ด์…˜ ์‘๋‹ต์„ ์œ„ํ•ด ์ œ๋„ค๋ฆญ์„ ํ™œ์šฉํ•ด DTO๋กœ ๊ตฌํ˜„ํ•˜์„ธ์š”.
    • ํŒจํ‚ค์ง€๋ช…: com.sprint.mission.discodeit.dto.response
    • ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

    • content: ์‹ค์ œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.
    • number: ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค.
    • size: ํŽ˜์ด์ง€์˜ ํฌ๊ธฐ์ž…๋‹ˆ๋‹ค.
    • totalElements: T ๋ฐ์ดํ„ฐ์˜ ์ด ๊ฐฏ์ˆ˜๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, null์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Slice ๋˜๋Š” Page ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ DTO๋ฅผ ์ƒ์„ฑํ•˜๋Š” Mapper๋ฅผ ๊ตฌํ˜„ํ•˜์„ธ์š”.
    • ํŒจํ‚ค์ง€๋ช…: com.sprint.mission.discodeit.mapper

    • ํ™•์žฅ์„ฑ์„ ์œ„ํ•ด ์ œ๋„ค๋ฆญ ๋ฉ”์†Œ๋“œ๋กœ ๊ตฌํ˜„ํ•˜์„ธ์š”.


3. ์‹ฌํ™” ์š”๊ตฌ์‚ฌํ•ญ

3-1. N+1 ๋ฌธ์ œ

  • N+1 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ฐพ๊ณ  ํ•ด๊ฒฐํ•ด๋ณด์„ธ์š”.


3-2. ์ฝ๊ธฐ์ „์šฉ ํŠธ๋žœ์žญ์…˜ ํ™œ์šฉ

  • ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” OSIV๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์„œ๋น„์Šค ๋ ˆ์ด์–ด์˜ ์กฐํšŒ ๋ฉ”์†Œ๋“œ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ•˜๊ณ , ์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜์„ ํ™œ์šฉํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์„ธ์š”.
    • OSIV ๋น„ํ™œ์„ฑํ™”ํ•˜๊ธฐ
      spring:
        jpa:
          open-in-view: false
      


3-3. ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ตœ์ ํ™”

  • ์˜คํ”„์…‹ ํŽ˜์ด์ง€๋„ค์ด์…˜๊ณผ ์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜ ๋ฐฉ์‹์˜ ์ฐจ์ด์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด์„ธ์š”.

์ด ๋‚ด์šฉ์€ PR์— ์ฒจ๋ถ€ํ•ด์ฃผ์„ธ์š”.

  • ๊ธฐ์กด์— ๊ตฌํ˜„ํ•œ ์˜คํ”„์…‹ ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜์œผ๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜์„ธ์š”.

โš ๏ธ ํ”„๋ก ํŠธ์—”๋“œ ์†Œ์Šค ์ฝ”๋“œ๋Š” ์ฐธ๊ณ ์šฉ์œผ๋กœ๋งŒ ํ™œ์šฉํ•˜์„ธ์š”. ์ˆ˜์ •ํ•˜์—ฌ ํ™œ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ด์–ด์ง€๋Š” ์š”๊ตฌ์‚ฌํ•ญ ๋˜๋Š” ๋ฏธ์…˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ์–ด๋ ค์›€์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


3-4. MapStruct ์ ์šฉ

  • Entity์™€ DTO๋ฅผ ๋งคํ•‘ํ•˜๋Š” ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๋ฅผย MapStructย ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•ด ๊ฐ„์†Œํ™”ํ•ด๋ณด์„ธ์š”.

Leave a comment