Group Study (2021-2022)/Spring Boot

[Spring Boot] 2์ฃผ์ฐจ 3์žฅ ์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ JPA๋กœ DB ๋‹ค๋ฃจ๊ธฐ

๋ญ‰๋ง๋ญ‰ 2021. 11. 15. 17:29

๐ŸŽ†[03์žฅ] ์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ JPA๋กœ DB ๋‹ค๋ฃจ๊ธฐ

  1. ํ”„๋กœ์ ํŠธ์— Spring Data JPA ์ ์šฉํ•˜๊ธฐ
  2. Spring Data JPA ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ
  3. ๋“ฑ๋ก/์ˆ˜์ •/์กฐํšŒ API ๋งŒ๋“ค๊ธฐ
  4. JPA Auditing์œผ๋กœ ์ƒ์„ฑ์‹œ๊ฐ„/์ˆ˜์ •์‹œ๊ฐ„ ์ž๋™ํ™”ํ•˜๊ธฐ

๐ŸŒธJPA ์†Œ๊ฐœ

  • ๊ด€๊ณ„ํ˜• DB๋Š” SQL๋งŒ ์ธ์‹ ๊ฐ€๋Šฅ. SQL์˜ ๋‹จ์ˆœ ๋ฐ˜๋ณต ์ž‘์—… ๋ฌธ์ œ
  • ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ ๋ฐœ์ƒ
    • ๊ด€๊ณ„ํ˜• DB: ์–ด๋–ป๊ฒŒ ์ €์žฅํ•  ๊ฒƒ์ธ์ง€์— ์ดˆ์ 
    • ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด: ๊ธฐ๋Šฅ๊ณผ ์†์„ฑ์„ ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌ
      • ๊ฐ์ฒด์ง€ํ–ฅ์—์„œ ๋งŒ๋“  ๋ถ€๋ชจ์™€ ์ž์‹ ๊ด€๊ณ„๊ฐ€ DB์—์„œ ๊นจ์ง → ์ƒ์†, 1:N ๋“ฑ ๋‹ค์–‘ํ•œ ๊ฐ์ฒด ๋ชจ๋ธ๋ง์„ DB์—์„œ ๊ตฌํ˜„ ๋ถˆ๊ฐ€ → ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ๋ชจ๋ธ๋ง์—๋งŒ ์ง‘์ค‘...
  • JPA๊ฐ€ ๋ฌธ์ œ ํ•ด๊ฒฐ : ํŒจ๋Ÿฌ๋‹ค์ž„ ์ผ์น˜์‹œ์ผœ์คŒ
    • ๊ฐœ๋ฐœ์ž - ๊ฐ์ฒด์ง€ํ–ฅ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ
    • JPA: ์ด๋ฅผ ๊ด€๊ณ„ํ˜• DB์— ๋งž๊ฒŒ SQL ๋Œ€์‹  ์ƒ์„ฑ, ์‹คํ–‰
  • ๊ฐ์ฒด ์ค‘์‹ฌ ๊ฐœ๋ฐœ! ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ, ์œ ์ง€๋ณด์ˆ˜์— ํŽธํ•จ

๐ŸŒธSpring Data JPA

  • ์ธํ„ฐํŽ˜์ด์Šค์ธ JPA๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ๊ตฌํ˜„์ฒด ํ•„์š”.
  • JPA (์ธํ„ฐํŽ˜์ด์Šค)← Hibernate (๊ตฌํ˜„์ฒด) ← Spring Data JPA (๋ชจ๋“ˆ)
  • Spring Data JPA๊ฐ€ ๋“ฑ์žฅํ•œ ์ด์œ 
  1. ๊ตฌํ˜„์ œ ๊ต์ฒด์˜ ์šฉ์ด์„ฑ : Hibernate ์™ธ์— ๋‹ค๋ฅธ ๊ตฌํ˜„์ฒด(Eclipse Link ๋“ฑ)๋กœ ์‰ฝ๊ฒŒ ๊ต์ฒด ๊ฐ€๋Šฅ
  2. ์ €์žฅ์†Œ ๊ต์ฒด์˜ ์šฉ์ด์„ฑ : ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์™ธ์— ๋‹ค๋ฅธ ์ €์žฅ์†Œ (MongoDB ๋“ฑ)๋กœ ์‰ฝ๊ฒŒ ๊ต์ฒด ๊ฐ€๋Šฅ
    • Spring Data์˜ ํ•˜์œ„ ํ”„๋กœ์ ํŠธ๋“ค์˜ ๊ธฐ๋ณธ์ ์ธ CRUD ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ฐ™์•„์„œ ์˜์กด์„ฑ๋งŒ ๊ต์ฒดํ•˜๋ฉด ๋จ

๐ŸŒธํ”„๋กœ์ ํŠธ์— Spring Data JPA ์ ์šฉํ•˜๊ธฐ

  • build.gradle ์˜์กด์„ฑ ๋“ฑ๋ก
    spring-boot-starter-data-jpa
    • ์Šคํ”„๋ง ๋ถ€ํŠธ์šฉ Spring Data JPA ์ถ”์ƒํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.
      ์Šคํ”„๋ง ๋ถ€ํŠธ ๋ฒ„์ „์— ๋งž์ถฐ ์ž๋™์œผ๋กœ JPA ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „ ๊ด€๋ฆฌ
    • h2
    • ์ธ๋ฉ”๋ชจ๋ฆฌ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค. ๋ณ„๋„์˜ ์„ค์น˜ ์—†์ด ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ๋งŒ์œผ๋กœ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ.
      ๋ฉ”๋ชจ๋ฆฌ์—์„œ๋งŒ ์‹คํ–‰๋ผ์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์žฌ์‹œ์ž‘๋งˆ๋‹ค ์ดˆ๊ธฐํ™”. → ํ…Œ์ŠคํŠธ ์šฉ๋„๋กœ ๋งŽ์ด ์‚ฌ์šฉ.
  • domain ํŒจํ‚ค์ง€ ์ƒ์„ฑ.
    • ๋„๋ฉ”์ธ: ๊ฒŒ์‹œ๊ธ€, ๋Œ“๊ธ€, ํšŒ์›, ์ •์‚ฐ, ๊ฒฐ์ œ ๋“ฑ ์†Œํ”„ํŠธ์›จ์–ด์— ๋Œ€ํ•œ ์š”๊ตฌ์‚ฌํ•ญ ํ˜น์€ ๋ฌธ์ œ ์˜์—ญ
  • domain ํŒจํ‚ค์ง€์— posts ํŒจํ‚ค์ง€์™€ Posts ํด๋ž˜์Šค ์ƒ์„ฑ
    • Posts ํด๋ž˜์Šค: ์‹ค์ œ DB์˜ ํ…Œ์ด๋ธ”๊ณผ ๋งค์นญ๋  ํด๋ž˜์Šค. Entity ํด๋ž˜์Šค๋ผ๊ณ ๋„ ํ•จ.
  • ๋” ์ค‘์š”ํ•œ (์ฃผ์š”) ์–ด๋…ธํ…Œ์ด์…˜์„ ํด๋ž˜์Šค์— ๊ฐ€๊น๊ฒŒ ๋‘๋Š” ๋ฐฐ์น˜
    • → ์ฝ”ํ‹€๋ฆฐ ๋“ฑ์˜ ์ƒˆ ์–ธ์–ด ์ „ํ™˜์œผ๋กœ ํ•„์š” ์—†์–ด์ง€๋ฉด ๋œ ์ค‘์š”ํ•œ ์–ด๋…ธํ…Œ์ด์…˜์ด ์ƒ์œ„์— ์žˆ์œผ๋‹ˆ๊นŒ ์‰ฝ๊ฒŒ ์‚ญ์ œ ๊ฐ€๋Šฅ
  • ๋กฌ๋ณต ์–ด๋…ธํ…Œ์ด์…˜์€ ์„œ๋น„์Šค ์ดˆ๊ธฐ ๊ตฌ์ถ• ๋‹จ๊ณ„์—์„œ ํ…Œ์ด๋ธ” ์„ค๊ณ„ (์—ฌ๊ธฐ์—์„  Entity ์„ค๊ณ„)๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ณ€๊ฒฝ๋  ๋•Œ ์ฝ”๋“œ ๋ณ€๊ฒฝ๋Ÿ‰ ์ตœ์†Œํ™”
  • PK๊ฐ’์€ Long type์˜ Auto_increment ์ถ”์ฒœ.
    • ์œ ๋‹ˆํฌ ํ‚ค(์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ ๋“ฑ)๋‚˜ ๋ณตํ•ฉํ‚ค(์—ฌ๋Ÿฌ ํ‚ค ์กฐํ•ฉ)๋กœ PK ์žก์œผ๋ฉด
      • FK ๋งบ์„ ๋•Œ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์—์„œ ๋ณตํ•ฉํ‚ค ์ „๋ถ€๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ฑฐ๋‚˜ ์ค‘๊ฐ„ ํ…Œ์ด๋ธ” ํ•˜๋‚˜ ๋” ๋‘ฌ์•ผํ•˜๋Š” ์ƒํ™ฉ ๋ฐœ์ƒ
      • ์ธ๋ฑ์Šค์— ์ข‹์€ ์˜ํ–ฅX
      • ์œ ๋‹ˆํฌํ•œ ์กฐ๊ฑด ๋ณ€๊ฒฝ ์‹œ PK ์ „์ฒด ์ˆ˜์ •ํ•ด์•ผ ํ•  ์ˆ˜๋„
    • → ์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ, ๋ณตํ•ฉํ‚ค ๋“ฑ์€ ์œ ๋‹ˆํฌ ํ‚ค๋กœ ๋ณ„๋„ ์ถ”๊ฐ€ ์ถ”์ฒœ
  • Entity ํด๋ž˜์Šค์—์„œ๋Š” ์ ˆ๋Œ€ Setter ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉ X.
    ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ๊ฐ’๋“ค์ด ์–ธ์ œ ์–ด๋””์„œ ๋ณ€ํ•ด์•ผ ํ•˜๋Š”์ง€ ์ฝ”๋“œ์ƒ ๋ช…ํ™• ๊ตฌ๋ถ„ ์–ด๋ ต... ์ฐจํ›„ ๊ธฐ๋Šฅ ๋ณ€๊ฒฝ ์‹œ ๋ณต์žกํ•ด์ง.
    → ํ•„๋“œ๊ฐ’ ๋ณ€๊ฒฝ ํ•„์š”ํ•˜๋ฉด ๋ชฉ์ ๊ณผ ์˜๋„๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉ
    • Setter ๋Œ€์‹  ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ตœ์ข…๊ฐ’์„ ์ฑ„์šฐ๊ณ  DB์— ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ํ•ด๋‹น ์ด๋ฒคํŠธ์— ๋งž๋Š” public ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ๊ฐ’ ๋ณ€๊ฒฝ
      • ์—ฌ๊ธฐ์„  ์ƒ์„ฑ์ž ๋Œ€์‹  @Builder๋ฅผ ํ†ตํ•ด ์ œ๊ณต๋˜๋Š” ๋นŒ๋” ํด๋ž˜์Šค ์‚ฌ์šฉ
        (์ƒ์„ฑ์ž ๊ณตํ†ต์ : ์ƒ์„ฑ ์‹œ์ ์— ๊ฐ’์„ ์ฑ„์›Œ์ฃผ๋Š” ์—ญํ• .
        ์ƒ์„ฑ์ž์™€ ์ฐจ์ด์ : ์ƒ์‚ฐ์ž๋Š” ์–ด๋Š ํ•„๋“œ์— ์–ด๋–ค ๊ฐ’ ์ฑ„์›Œ์•ผํ• ์ง€ ๋ช…ํ™• ์ง€์ • ๋ถˆ๊ฐ€)
  • JpaRepository ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ : Posts ํด๋ž˜์Šค๋กœ DB์— ์ ‘๊ทผํ•˜๊ฒŒ ํ•ด์ค„ ์ธํ„ฐํŽ˜์ด์Šค. DB ๋ ˆ์ด์–ด ์ ‘๊ทผ์ž์ž„.
    • ์ธํ„ฐํŽ˜์ด์Šค ๋งŒ๋“œ๋Š” ๊ฒŒ ์—†์–ด์„œ ํ—ค๋งธ๋Š”๋ฐ new class ์ƒ์„ฑํ•˜๋ฉด interface ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค..!!
    • JpaRepository ์ธํ„ฐํŽ˜์ด์Šค ์ด๋ฆ„์€ PostRepository๋กœ ์ง€์ •ํ•จ
    • JpaRepository<Entity ํด๋ž˜์Šค, PK ํƒ€์ž…> ์ƒ์† → ๊ธฐ๋ณธ์  CRUD ๋ฉ”์†Œ๋“œ ์ž๋™ ์ƒ์„ฑ
    • Entity ํด๋ž˜์Šค์™€ ๊ธฐ๋ณธ Entity Repository๋Š” ํ•จ๊ป˜ ์œ„์น˜ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋„๋ฉ”์ธ ํŒจํ‚ค์ง€์—์„œ ํ•จ๊ป˜ ๊ด€๋ฆฌ
      (๊ธฐ๋ณธ Repository ์—†์œผ๋ฉด Entity ํด๋ž˜์Šค๋Š” ์ œ์—ญํ•  ๋ถˆ๊ฐ€)

๐ŸŒธSpring Data JPA ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

  • Test์˜ domain ํŒจํ‚ค์ง€์— posts ํŒจํ‚ค์ง€, PostsRepositoryTest ํด๋ž˜์Šค ์ƒ์„ฑ
  • ํ…Œ์ŠคํŠธ ์‹คํ–‰ํ•ด๋ณด๋ฉด ํ†ต๊ณผํ•จ.
  • ์‹ค์ œ๋กœ ์‹คํ–‰๋œ ์ฟผ๋ฆฌ๋ฅผ ๋กœ๊ทธ๋กœ ๋ณด๋ ค๋ฉด?
    ์‹ค์ œ๋กœ ์‹คํ–‰๋œ ์ฟผ๋ฆฌ๋ฅผ MySQL ๋ฒ„์ „ ๋กœ๊ทธ๋กœ ๋ณด๋ ค๋ฉด?
    // application.properties
    spring.jpa.show_sql=true
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

๐ŸŒธ๋“ฑ๋ก/์ˆ˜์ •/์กฐํšŒ API ๋งŒ๋“ค๊ธฐ

  • API๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ด 3๊ฐœ์˜ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”
    1. Request ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ Dto
    2. API ์š”์ฒญ์„ ๋ฐ›์„ Controller
    3. ํŠธ๋žœ์žญ์…˜, ๋„๋ฉ”์ธ ๊ธฐ๋Šฅ ๊ฐ„์˜ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋Š” Service
      • ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ๋Š” Service์˜ ์—ญํ• ์ด X
  • Spring ์›น ๊ณ„์ธต

    • Web Layer
      • ์ปจํŠธ๋กค๋Ÿฌ(@Controller)์™€ JSP/Freemarker ๋“ฑ์˜ ๋ทฐ ํ…œํ”Œ๋ฆฟ ์˜์—ญ
      • ํ•„ํ„ฐ(@Filter), ์ธํ„ฐ์…‰ํ„ฐ, ์ปจํŠธ๋กค๋Ÿฌ ์–ด๋“œ๋ฐ”์ด์Šค(@ControllerAdvice) ๋“ฑ ์™ธ๋ถ€ ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๋Œ€ํ•œ ์ „๋ฐ˜์ ์ธ ์˜์—ญ
    • Service Layer
      • @Service์— ์‚ฌ์šฉ๋˜๋Š” ์„œ๋น„์Šค ์˜์—ญ
      • ์ผ๋ฐ˜์ ์œผ๋กœ Controller์™€ Dao์˜ ์ค‘๊ฐ„ ์˜์—ญ์—์„œ ์‚ฌ์šฉ
      • @Transactional์ด ์‚ฌ์šฉ๋ผ์•ผ ํ•˜๋Š” ์˜์—ญ
    • Repository Layer
      • Database์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ์— ์ ‘๊ทผํ•˜๋Š” ์˜์—ญ
      • Dao (Data Access Object) ์˜์—ญ
    • Dtos
      • Dto (Data Transfer Object)๋Š” ๊ณ„์ธต ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ๊ตํ™˜์„ ์œ„ํ•œ ๊ฐ์ฒด. Dtos๋Š” ์ด๋“ค์˜ ์˜์—ญ
      • ex) ๋ทฐ ํ…œํ”Œ๋ฆฟ ์—”์ง„์—์„œ ์‚ฌ์šฉ๋  ๊ฐ์ฒด๋‚˜ Repository Layer์—์„œ ๊ฒฐ๊ณผ๋กœ ๋„˜๊ฒจ์ค€ ๊ฐ์ฒด ๋“ฑ
    • Domain Model
      • ๋„๋ฉ”์ธ์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ๊ฐœ๋ฐœ ๋Œ€์ƒ์„ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๋™์ผํ•œ ๊ด€์ ์—์„œ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ณ  ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‹จ์ˆœํ™”์‹œํ‚จ ๊ฒƒ
      • ex) ํƒ์‹œ ์•ฑ) ๋ฐฐ์ฐจ, ํƒ‘์Šน, ์š”๊ธˆ ๋“ฑ์ด ๋ชจ๋‘ ๋„๋ฉ”์ธ
      • @Entity๊ฐ€ ์‚ฌ์šฉ๋œ ์˜์—ญ
      • VO์ฒ˜๋Ÿผ ๊ฐ’ ๊ฐ์ฒด๋„ ๋„๋ฉ”์ธ ๋ชจ๋ธ์— ํ•ด๋‹นํ•˜๊ธฐ์— ๋ฌด์กฐ๊ฑด DB ํ…Œ์ด๋ธ”๊ณผ ๊ด€๊ณ„ ์žˆ์–ด์•ผ ํ•˜๋Š” ๊ฑด ์•„๋‹˜.
      • Web, Service, Repository, Dto, Domain์˜ 5๊ฐ€์ง€ ๋ ˆ์ด์–ด์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ์ฒ˜๋ฆฌ๋Š” Domain์ด ๋‹ด๋‹น
  • service : ํŠธ๋žœ์žญ์…˜, ๋„๋ฉ”์ธ ๊ฐ„์˜ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋Š” ์˜์—ญ
  • ๋“ฑ๋ก
    • web/PostsApicontroller.java
    • service/PostsService.java
      @RequiredArgsConstructor
      : ๋กฌ๋ณต ์–ด๋…ธํ…Œ์ด์…˜. final์ด ์„ ์–ธ๋œ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ธ์ž๊ฐ’์œผ๋กœ ํ•˜๋Š” ์ƒ์„ฑ์ž ์ƒ์„ฑ.
      ์ƒ์„ฑ์ž๋ฅผ ์ง์ ‘ ์•ˆ ์“ด ์ด์œ : ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์˜์กด์„ฑ ๊ด€๊ณ„๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ƒ์„ฑ์ž ์ฝ”๋“œ๋ฅผ ๊ณ„์† ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€ ํ•ด๊ฒฐ ์œ„ํ•ด
    • web/dto/PostsSaveRequestDto.java
    • Entity ํด๋ž˜์Šค
      • DB์™€ ๋งž๋‹ฟ์€ ํ•ต์‹ฌ ํด๋ž˜์Šค.
      • Entity ํด๋ž˜์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ด๋ธ” ์ƒ์„ฑ, ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ.
      • ๋ณ€๊ฒฝ๋˜๋ฉด ์—ฌ๋Ÿฌ ํด๋ž˜์Šค์— ์˜ํ–ฅ ๋ผ์นจ.
      • ์ ˆ๋Œ€ Request/Response ํด๋ž˜์Šค๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋จ.
        → Request/Response์šฉ Dto๋Š” View๋ฅผ ์œ„ํ•œ ํด๋ž˜์Šค๋ผ ์ •๋ง ์ž์ฃผ ๋ณ€๊ฒฝ ํ•„์š”.
        View Layer์™€ DB Layer์˜ ์—ญํ•  ๋ถ„๋ฆฌ ์ฒ ์ €ํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒŒ ์ข‹์Œ.
        Controller์—์„œ ๊ฒฐ๊ด๊ฐ’์œผ๋กœ ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์„ ์กฐ์ธํ•ด์„œ ์ค˜์•ผ ํ•  ๊ฒฝ์šฐ๊ฐ€ ๋นˆ๋ฒˆํ•˜๋ฏ€๋กœ Entity ํด๋ž˜์Šค๋งŒ์œผ๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ.
        Entity ํด๋ž˜์Šค์™€ Controller์—์„œ ์“ธ Dto๋Š” ๋ถ„๋ฆฌ ํ•„์ˆ˜.
    • ํ…Œ์ŠคํŠธ - web/PostsApiControllerTest.java
  • ์ˆ˜์ •
    • web/PostsApiController
    • web/dto/PostResponseDto
    • service/posts/PostService
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‹คํ–‰ → update๋œ ๊ฑฐ ํ™•์ธ ๊ฐ€๋Šฅ
  • ์กฐํšŒ
    • resources/application.properties
      main์—์„œ Application.java ์ฝ”๋“œ ์‹คํ–‰ ํ›„ ์ฝ˜์†”์—์„œ tomcat 8080 ์‹คํ–‰๋œ ๊ฑฐ ํ™•์ธ ํ›„
      http://localhost:8080/h2-console๋กœ ์ด๋™

โ“๐Ÿ”ซTrouble Shooting!

tomcate 8080 ํฌํŠธ ์—ด๋ฆฐ ๊ฑฐ ํ™•์ธ๋๋Š”๋ฐ ํŽ˜์ด์ง€ ์ ‘์†์ด ์•ˆ ๋˜๋Š” ๋ฌธ์ œ
→ resources/application.properties๋ฅผ test ์•ˆ์— ๋’€๋Š”๋ฐ main ์•ˆ์˜ resources/application.properties์— h2 ๊ด€๋ จ ์†์„ฑ ์ ์–ด์ค˜์•ผํ•จ

JDBC URL์— jdbc:h2:mem:testdb์ž…๋ ฅ ํ›„ CONNECT ๋ˆ„๋ฅด๊ธฐ

 

posts ํ…Œ์ด๋ธ” ์žˆ๋Š” ๊ฑฐ ํ™•์ธํ•˜๊ณ  ์ฟผ๋ฆฌ ์‹คํ–‰ํ•ด๋ณด๊ธฐ

 

insert into posts (author, content, title) values ('author', 'content', 'title');

 

http://localhost:8080/api/v1/posts/1 ๋กœ ์ด๋™ํ•˜๋ฉด ๋ณผ ์ˆ˜ ์žˆ์Œ

 

๐ŸŒธJPA Auditing์œผ๋กœ ์ƒ์„ฑ์‹œ๊ฐ„/์ˆ˜์ •์‹œ๊ฐ„ ์ž๋™ํ™”ํ•˜๊ธฐ

  • entity์—๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ์˜ ์ƒ์„ฑ์‹œ๊ฐ„, ์ˆ˜์ •์‹œ๊ฐ„์ด ๋ณดํ†ต ํฌํ•จ๋˜๋Š”๋ฐ ๋ชจ๋“  ํ…Œ์ด๋ธ”๊ณผ ์„œ๋น„์Šค ๋ฉ”์†Œ๋“œ์— ๋‹จ์ˆœํ•˜๊ณ  ๋ฐ˜๋ณต์ ์ธ ์ด ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋˜๋Š” ๊ฑธ ํ•ด๊ฒฐํ•˜๊ณ ์ž JPA Auditing ์‚ฌ์šฉ
  • domain/BaseTimeEntity.java
    ์ด BaseTimeEntity ํด๋ž˜์Šค๋Š” ๋ชจ๋“  Entity์˜ ์ƒ์œ„ ํด๋ž˜์Šค๊ฐ€ ๋˜์–ด Entity๋“ค์˜ createdDate, modifiedDate๋ฅผ ์ž๋™ ๊ด€๋ฆฌ
  • Posts ํด๋ž˜์Šค๊ฐ€ BaseTimeEntity๋ฅผ ์ƒ์†๋ฐ›๋„๋ก extends ์ž‘์„ฑ
    • public class Posts extends BaseTimeEntity
  • JPA Auditing ์–ด๋…ธํ…Œ์ด์…˜๋“ค์„ ๋ชจ๋‘ ํ™œ์„ฑํ™” ๊ฐ€๋Šฅํ•˜๊ฒŒ Application ํด๋ž˜์Šค์— ํ™œ์„ฑํ™” ์–ด๋…ธํ…Œ์ด์…˜ ํ•˜๋‚˜ ์ถ”๊ฐ€
    • @EnableJpaAuditing // JPA Auditing ํ™œ์„ฑํ™”
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ํ›„ ์‹คํ–‰
    ๊ฒฐ๊ณผ ๋ณผ ์ˆ˜ ์žˆ์Œ
  • BaseTimeEntity๋งŒ ์ƒ์†๋ฐ›์œผ๋ฉด Entity์˜ ๋“ฑ๋ก์ผ, ์ˆ˜์ •์ผ ์ด์Šˆ๋Š” ์ž๋™ ํ•ด๊ฒฐ