Skip to content

Latest commit

ย 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
ย 
ย 

README.md

๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค

์ฐจ์ด์ 

  • ์Šคํ”„๋ง์˜ ์ž๋ฐ”๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด
  • ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
  • ์ž๋ฐ”์˜ ๋ชฉํ‘œ โ†’ ์บก์Аํ™”/์ƒ์†/๋‹คํ˜•์„ฑ์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ
  • ๊ด€๊ณ„ํ˜• DB์˜ ๋ชฉํ‘œ โ†’ ๋ฐ์ดํ„ฐ๋ฅผ ์ •๊ตํ•˜๊ฒŒ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ
  • ์ฆ‰, ์Šคํ”„๋ง ๋ถ€ํŠธ๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด CRUD ์ฟผ๋ฆฌ๋ฅผ ๋‹ค ์งœ๊ณ , ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ SQL๋กœ ๋ฐ”๊พธ๊ณ  SQL์ฟผ๋ฆฌ๋ฅผ ์ž๋ฐ”๋กœ ๋ฐ”๊พธ๋Š” ๋ฒˆ๊ฑฐ๋กœ์šด ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค
  • DB์—์„œ ์กฐํšŒํ•œ ํ…Œ์ด๋ธ” ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋“ค์„ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•˜๊ณ  ๋ณ€๊ฒฝ๋œ ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๋‹ค์‹œ SQL๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๊ด€๊ณ„ํ˜• DB์— ๋ฐ˜์˜ํ•ด์•ผ ํ•œ๋‹ค

JPA

  • ์ž๋ฐ” ์ง„์˜์—์„œ ORM(๊ฐ์ฒด ๊ด€๊ณ„ํ˜• ๋งคํ•‘) ๊ธฐ์ˆ ์˜ ํ‘œ์ค€์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ชจ์Œ
  • ORM : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํด๋ž˜์Šค์™€ ๊ด€๊ณ„ํ˜• DB์˜ ํ…Œ์ด๋ธ”์„ ๋งคํ•‘(์—ฐ๊ฒฐ)ํ•˜๋Š” ๊ธฐ์ˆ 
  • ์ฆ‰, JPA๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์„œ ๋ฐ˜๋ณต์ ์ธ CRUD SQL ์ฟผ๋ฆฌ๋ฌธ์„ ์ง์ ‘ ์งค ํ•„์š”๊ฐ€ ์—†์ด ์ž๋™์œผ๋กœ ๋งคํ•‘ํ•˜์—ฌ ๋‚ ๋ ค์ค€๋‹ค
  • ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ชจ์Œ์ธ ๋งˆ๋Š  ์‹ค์ œ๋กœ ๊ตฌํ˜„๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์™€ ๋งคํ•‘์„ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค

์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ ๋ฐ ์„ค๊ณ„ ๊ตฌ์กฐ

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

๋Œ€ํ‘œ์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค

  • ํŒŒ์‚ฌ๋“œ ํŒจํ„ด ๊ตฌ์กฐ
  • ๋„๋ฉ”์ธํ˜• ๊ตฌ์กฐ
  • ๊ณ„์ธตํ˜• ๊ตฌ์กฐ
  • ํ—ฅ์‚ฌ๊ณ ๋‚  ๊ตฌ์กฐ

๊ฐ ๊ตฌ์กฐ์—๋Š” ๋ชจ๋‘ ๊ฐ์ž์˜ ์žฅ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค. ๊ทธ ์ค‘ ๋„๋ฉ”์ธํ˜• ๊ตฌ์กฐ๋Š” ERD๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋„๋ฉ”์ธ์„ ๋งŒ๋“ค๊ธฐ ์‰ฝ๊ณ , ํ˜‘์—… ์‹œ ๋„๋ฉ”์ธ๋ณ„๋กœ ์—ญํ• ์„ ๋ถ„๋‹ดํ•˜๊ธฐ๋„ ์‰ฝ๋‹ค

๋„๋ฉ”์ธํ˜• ๊ตฌ์กฐ

  • ๋งŒ๋“ค์–ด์ง„ DRD์˜ ๋„๋ฉ”์ธ์„ ์‚ดํŽด๋ณด๋ฉด ํฌ๊ฒŒ 4๊ฐ€์ง€๋กœ ๋‚˜๋‰˜๊ฒŒ ๋œ๋‹ค. ์‚ฌ์šฉ์ž, ๋ฏธ์…˜, ๋ฆฌ๋ทฐ, ๊ฐ€๊ฒŒ์ด๋‹ค
  • ์ด๊ฑธ ๊ธฐ์ค€์œผ๋กœ ์ƒ์„ฑ๋œ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค
 project root
 โ”œโ”€โ”€ domain
 โ”‚   โ”œโ”€โ”€ member
 โ”‚   โ”œโ”€โ”€ mission
 โ”‚   โ”œโ”€โ”€ review
 โ”‚   โ””โ”€โ”€ store
 โ”‚     โ”œโ”€โ”€ controller
 โ”‚     โ”œโ”€โ”€ converter : DTO โ†’ Entity ๊ฐ„์˜ ๋ณ€ํ™˜์„ ๋‹ด๋‹น (์„œ๋น„์Šค ๋ ˆ์ด์–ด๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ)
 โ”‚     โ”œโ”€โ”€ dto
 โ”‚     โ”œโ”€โ”€ entity
 โ”‚     โ”œโ”€โ”€ repository
 โ”‚     โ””โ”€โ”€ service
 โ””โ”€โ”€ global : ์ „์—ญ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด(์„ค์ •, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋“ฑ)๋ฅผ ๋‹ด๋Š” ๋””๋ ‰ํ† ๋ฆฌ

์—”ํ‹ฐํ‹ฐ ๋งคํ•‘

์‚ฌ์šฉ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค

  • @Entity : ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ JPA์˜ ์—”ํ‹ฐํ‹ฐ์ž„์„ ์˜๋ฏธ
  • @Table : DB์˜ ํ…Œ์ด๋ธ”์„ ์ •์˜. (name="member") ๋“ฑ์œผ๋กœ ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„์„ ๋ช…์‹œํ•˜๋Š” ๋“ฑ์˜ ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • @Id : ํ•ด๋‹น ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๊ฐ€ ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ์˜ PK๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธ
  • @GeneratedValue : ์ฃผ๋กœ id ํ•„๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ. ๊ฐ’์„ ๋„ฃ์–ด์ฃผ์ง€ ์•Š๋”๋ผ๋„ ์ž๋™์œผ๋กœ ๋ฒˆํ˜ธ๊ฐ€ ์ƒ์„ฑ๋จ
  • @Column : ํ•ด๋‹น ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๊ฐ€ ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ์˜ ์นผ๋Ÿผ์ด๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธ. (name="gender") ๋“ฑ์œผ๋กœ ์นผ๋Ÿผ๋ช…์„ ๋ช…์‹œํ•˜๋Š” ๋“ฑ์˜ ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • @Enumerated : Enum์„ ์‚ฌ์šฉํ•  ๋•Œ, ๋ฐ์ดํ„ฐ์˜ ํ˜•ํƒœ๋ฅผ ๋ช…์‹œํ™”
  • @NoArgsConstructor : ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. JPA ์—”ํ‹ฐํ‹ฐ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ํ•„์š”๋กœ ํ•˜๋ฏ€๋กœ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๋ฐ˜๋“œ์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค. ๋‹ค๋งŒ ๊ฐœ๋ฐœ์ž๋Š” ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋กœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ผ์ด ๊ฑฐ์˜ ์—†์œผ๋ฏ€๋กœ (access = AccessLevel.PROTECTED) ์˜ต์…˜์„ ์ด์šฉํ•ด ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ protected๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค

DBMS ๋‚ด๋ถ€์—์„œ ์˜ˆ์•ฝ์–ด, ํ‚ค์›Œ๋“œ๋กœ ์˜ˆ์•ฝ๋œ ๋‹จ์–ด(ex. User)๋ฅผ ๋‚ด ํ”„๋กœ์ ํŠธ์˜ ํด๋ž˜์Šค๋ช…์ด๋‚˜ ์นผ๋Ÿผ๋ช…์œผ๋กœ ์“ฐ์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค!

์„ธ๋ถ€ ์„ค์ •

// ์ด๋ฆ„ ์นผ๋Ÿผ์€ 3๊ธ€์ž๋กœ ์ œํ•œ๋˜๋ฉฐ null๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์—†๋‹ค
@Column(length = 3, nullabel = false)
private String name;

์ดˆ๊ธฐ๊ฐ’ ์ง€์ •

// ์ด๋ฆ„ ์นผ๋Ÿผ์€ ๋ฌธ์ž์—ด Enum ํด๋ž˜์Šค์˜ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค
// null๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์—†์œผ๋ฉฐ ๊ฐ’์„ ๋„ฃ์ง€ ์•Š์„ ๊ฒฝ์šฐ NONE์œผ๋กœ ์ดˆ๊ธฐํ™”๋œ๋‹ค
@Column(nullabel = false)
@Enumerated(EnumType.STRING)
@Builder.Default        // lombok ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ง€์›
private Gender gender = Gender.NONE;

์ด๋•Œ @Buileder.Default๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ƒ๋‹จ ํด๋ž˜์Šค์— @Builder ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค

์ƒ์„ฑ/์ˆ˜์ • ์ผ์ž ์ž๋™ ๊ธฐ์ž…

// ์ƒ์„ฑ ์ผ์ž
@CreatedDate
@Column(nullabel = false)
private LocalDateTime createAt;
// ์ˆ˜์ • ์ผ์ž
@LastModifiedDate
@Column(nullabel = false)
private LocalDateTime updateAt;

์ด๋•Œ @CreatedDate์™€ @LastModifiedDate๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ƒ๋‹จ ํด๋ž˜์Šค์— @EnableJpaAuditing์™€ @EntityListeners(AuditingEntityListener.class) ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค

BaseEntity ์„ค์ •

  • ๋งŒ์•ฝ CreatedAt, UpdatedAt์ฒ˜๋Ÿผ ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ์—์„œ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด BaseEntity ์„ค์ •์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
  • BaseEntity ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ๊ณตํ†ต๋œ ์†์„ฑ์„ ์ •์˜ํ•˜๊ณ  ์›ํ•˜๋Š” ํด๋ž˜์Šค์—์„œ extends BaseEntity ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค
  • ์ผ๋ฐ˜์ ์ธ ์นผ๋Ÿผ์€ ์กฐ์ธ ์‹œ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฆ„์„ ๋‹ค๋ฅด๊ฒŒ ๋งคํ•‘ํ•˜๋Š” ๊ฒƒ(user_name, shop_name ๋“ฑ)์ด ์ผ๋ฐ˜์ ์ด์ง€๋งŒ BaseEntity์˜ ๊ณตํ†ต ์ปฌ๋Ÿผ์€ ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ์—์„œ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๋ฏ€๋กœ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ๊ฐ™์€ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค
  • ๋˜ํ•œ created_at์ด๋‚˜ updated_at ๊ฐ™์€ Auditing ์ปฌ๋Ÿผ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ๋””๋ฒ„๊น…ํ•  ๋•Œ ์œ ์šฉํ•œ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋‘ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•˜๋Š” ์กฐ์ธ ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉ๋  ์ผ์ด ์—†๋‹ค

์—ฐ๊ด€ ๊ด€๊ณ„ ์ง€์ •

  • N:M ์—ฐ๊ด€๊ด€๊ณ„์˜ ๊ฒฝ์šฐ ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๊ณ  ๊ทธ๊ณณ์—์„œ ์—ฐ๊ด€ ๊ด€๊ณ„๋ฅผ ์ง€์ •ํ•œ๋‹ค
  • @OneToOne : 1:1 ์—ฐ๊ด€๊ด€๊ณ„ ์„ค์ •
  • @ManyToOne : 1:N ๊ด€๊ณ„์—์„œ ์ด ์—”ํ‹ฐํ‹ฐ๊ฐ€ N์ž„์„ ์ •์˜ํ•œ๋‹ค
  • @JoinColumn : ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ง„ ํด๋ž˜์Šค(ํ…Œ์ด๋ธ”)์ด ์ด ์—ฐ๊ด€ ๊ด€๊ณ„์˜ ์ฃผ์ธ์ž„์„(FK์˜ ์ฃผ์ธ์ž„์„) ์„ค์ •ํ•œ๋‹ค
  • ์ด๋•Œ ~ToOne์˜ ๊ฒฝ์šฐ @JoinColumn์—์„œ (fatch = FetchType.LAZY)๋ฅผ ๋ช…์‹œํ•ด ์ง€์—ฐ ๋กœ๋”ฉ์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค
  • ๋งคํ•‘ ๋‹นํ•˜๋Š” ์ชฝ์˜ ๊ฒฝ์šฐ @OneToOne ๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜์—์„œ (mappedBy = โ€œreply")๋ฅผ ๋ช…์‹œํ•˜๋ฉด ๋œ๋‹ค

N+1 ๋ฌธ์ œ

FetchType.EAGER์˜ ์ž‘๋™ ๋ฐฉ์‹ ๋ฐ ๋ฌธ์ œ์ 

  • FetchType.EAGER์„ ์„ค์ •ํ•˜๋ฉด, ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋กœ๋”ฉํ•  ๋•Œ ์—ฐ๊ด€๋œ(FK๋กœ ๋ฌถ์ธ) ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ๋‚ด์šฉ๊นŒ์ง€ ์ฆ‰์‹œ ํ•œ ๋ฒˆ์— ๊ฐ™์ด ๋กœ๋”ฉ๋œ๋‹ค
  • ์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์›ํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๊นŒ์ง€ ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋งŒ๋“ค์–ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ์ €ํ•˜ํ•œ๋‹ค
  • ๋˜ํ•œ ORM(Object-Relational Mapping)์˜ ์„ค๊ณ„ ์›์น™ ์ค‘ ํ•˜๋‚˜์ธ ํ•„์š”ํ•  ๋•Œ ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ์›์น™์„ ์œ„๋ฐฐํ•œ๋‹ค
  • ๋”ฐ๋ผ์„œ JPA/ํ•˜์ด๋ฒ„๋„ค์ดํŠธ์—์„œ๋Š” EAGER ๋Œ€์‹  FetchType.LAZY๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ๊ถŒ์žฅํ•œ๋‹ค

N+1 ๋ฌธ์ œ์˜ ๋ฐœ์ƒ ์›์ธ ๋ฐ FetchType๊ณผ์˜ ๊ด€๊ณ„

N+1 ๋ฌธ์ œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ FetchType.LAZY์ผ ๋•Œ ํ”ํžˆ ๋ฐœ์ƒํ•˜์ง€๋งŒ FetchType.EAGER์—์„œ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. LAZY์ผ ๋•Œ : ํ•™์ƒ ๋ชฉ๋ก ํ…Œ์ด๋ธ”์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ฉ”์ธ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋œ๋‹ค โ†’ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ…Œ์ด๋ธ” ๋‚ด ๋ชจ๋“  ํ•™์ƒ์— ์ ‘๊ทผํ•˜๋ ค ํ•˜๋ฉด JPA๋Š” ๊ฐ ์—”ํ‹ฐํ‹ฐ๋งˆ๋‹ค ์—ฐ๊ด€๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด N๋ฒˆ์˜ ์ถ”๊ฐ€ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค โ†’ ์ด 1 + N ๋ฒˆ์˜ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค
  2. EAGER์ผ ๋•Œ : FetchType.EAGER๋Š” ์—ฐ๊ด€๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฆ‰์‹œ ๋กœ๋”ฉํ•˜์ง€๋งŒ JPA ๊ตฌํ˜„์ฒด(ํ•˜์ด๋ฒ„๋„ค์ดํŠธ)๋Š” ์ด ์ฆ‰์‹œ ๋กœ๋”ฉ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋‚ด๋ถ€์ ์œผ๋กœ N+1 ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค. ์ฆ‰, ์œ„์˜ LAZY์™€ ์™„์ „ํžˆ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค โ†’ FetchType.EAGER์€ N+1 ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ์ฑ…์ด ์•„๋‹ˆ๋ฉฐ, ์˜คํžˆ๋ ค ๊ฐœ๋ฐœ์ž์˜ ์˜๋„์™€ ๋‹ฌ๋ฆฌ ๋Œ€๋Ÿ‰์˜ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค!

FATCH JOIN

  • FATCH JOIN์€ N+1 ๋ฌธ์ œ์˜ ๊ทผ๋ณธ์ ์ธ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ JPQL/QueryDSL๋กœ JOIN FETCH ๊ตฌ๋ฌธ์„ ์ž‘์„ฑํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ์ œ์–ดํ•œ๋‹ค
  • ํ•„์š”ํ•œ ํ…Œ์ด๋ธ”์˜ ์ •๋ณด๋“ค์„ join ํ›„ ๊ฐ€์ ธ์˜ด์œผ๋กœ์จ 1๋ฒˆ์˜ ์ฟผ๋ฆฌ๋กœ ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ฌ ์ˆ˜ ์žˆ๋‹ค

@EntityGraph

  • @EntityGraph๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ JPQL์—์„œ JOIN FETCH ๊ตฌ๋ฌธ์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ JPA ๊ตฌํ˜„์ฒด(ํ•˜์ด๋ฒ„๋„ค์ดํŠธ)๊ฐ€ @EntityGraph์˜ ์ •์˜๋ฅผ ๋ณด๊ณ  ๊ฐ€์žฅ ํšจ์œจ์ ์ธ ์ฟผ๋ฆฌ(๋Œ€๋ถ€๋ถ„ JOIN์„ ์‚ฌ์šฉํ•œ ์ฟผ๋ฆฌ)๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ด์ค€๋‹ค
  • JPQL ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด ๋ฉ”์†Œ๋“œ ์ด๋ฆ„์ด๋‚˜ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ N+1 ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด์ง„๋‹ค
  • ๊ทธ๋Ÿฌ๋‚˜ ๋ณต์žกํ•œ ์กฐ๊ฑด ๋“ฑ์˜ ๋™์  ์ฟผ๋ฆฌ์—์„œ๋Š” FETCH JOIN์„ ์ด์šฉํ•ด ์ฟผ๋ฆฌ๋ฌธ์„ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋” ์ ํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค

๊ฒฐ๋ก  : N+1 ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” FetchType.LAZY๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ํŠน์ • ์ƒํ™ฉ์—์„œ ๋งŽ์€ ์–‘์˜ ์—ฐ๊ด€ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•  ๋•Œ FETCH JOIN ๋˜๋Š” @EntityGraph๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ์ตœ์ ํ™”ํ•˜์—ฌ์•ผ ํ•œ๋‹ค

casecade ์„ค์ •

  • ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์„ ํ•  ๊ฒฝ์šฐ cascade ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋‹ค
  • cascade๋Š” ํ•œ ํ…Œ์ด๋ธ”์„ ์ˆ˜์ •, ์‚ญ์ œ ํ•  ๋•Œ ์—ฐ๊ด€๋œ ๋ชจ๋“  ํ…Œ์ด๋ธ”์„ ํ•จ๊ป˜ ์ˆ˜์ •, ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค
  • cascade ์„ค์ •์—์„œ ์„ ํƒ ๊ฐ€๋Šฅํ•œ ์˜ต์…˜์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค
    • ALL: ๋ชจ๋“  cascade ์ž‘์—… ์ „ํŒŒ
    • DETACH: ์—”ํ‹ฐํ‹ฐ ๋ถ„๋ฆฌ ์‹œ, ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ๋„ ๋ถ„๋ฆฌ
    • MERGE: ์—”ํ‹ฐํ‹ฐ ๋ณ‘ํ•ฉ ์‹œ, ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ๋„ ๋ณ‘ํ•ฉ
    • PERSIST: ์—”ํ‹ฐํ‹ฐ ์ €์žฅ ์‹œ, ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ๋„ ์ €์žฅ
    • REFRESH: ์—”ํ‹ฐํ‹ฐ ์ƒˆ๋กœ๊ณ ์นจ ์‹œ, ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ๋„ ์ƒˆ๋กœ๊ณ ์นจ
    • REMOVE: ์—”ํ‹ฐํ‹ฐ ์‚ญ์ œ ์‹œ, ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ๋„ ์‚ญ์ œ
  • ๋‹จ๋ฐฉํ–ฅ ๋งคํ•‘์—์„  ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ์ด ๊ฒฝ์šฐ ์„œ๋น„์Šค ํด๋ž˜์Šค์—์„œ ์—ฐ๊ด€๋œ ๋ฐ์ดํ„ฐ๋“ค์„ ์ง์ ‘ ์ง€์›Œ์ฃผ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค

๊ณ„์ธตํ˜• ๊ตฌ์กฐ vs ๋„๋ฉ”์ธํ˜• ๊ตฌ์กฐ

๊ณ„์ธตํ˜• ๊ตฌ์กฐ

  • ๋„๋ฉ”์ธ, ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ, ์„œ๋น„์Šค, ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๊ณ„์ธต์„ ๋‚˜๋ˆ„๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ์‹
  • ์ƒˆ๋กœ์šด ๋„๋ฉ”์ธ ์ถ”๊ฐ€ ์‹œ ๋ชจ๋“  ๊ณ„์ธต์— ์ถ”๊ฐ€ ํŒŒ์ผ์ด ํ•„์š”ํ•˜๋‹ค
  • ๊ฐ™์€ ์—ญํ• ์„ ํ•˜๋Š” ํŒŒ์ผ๋“ค์ด ํ•œ ํด๋”์— ๋ชจ์—ฌ์žˆ๋‹ค
  • ๊ตฌ์กฐ๊ฐ€ ๋‹จ์ˆœํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค
  • ์ž‘์€ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜๋‹ค

๋„๋ฉ”์ธํ˜• ๊ตฌ์กฐ

  • ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ•ต์‹ฌ ์—…๋ฌด ๋‹จ์œ„์ธ ๋„๋ฉ”์ธ, ์ฆ‰ ๋ช…์‚ฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๋ฐฉ์‹
  • ์ƒˆ๋กœ์šด ๋„๋ฉ”์ธ ์ถ”๊ฐ€ ์‹œ ํ•ด๋‹น ๋„๋ฉ”์ธ์˜ ํด๋”๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋˜๋ฏ€๋กœ ๋ชจ๋“ˆํ™”์— ์œ ๋ฆฌํ•˜๋‹ค
  • ํ•œ ๋„ใ…๋ฉ”์ธ์˜ ๋ชจ๋“  ๊ด€๋ จ ํŒŒ์ผ๋“ค์ด ํ•œ ํด๋”์— ๋ชจ์—ฌ ์žˆ๋‹ค
  • ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ๊ณ  ์‘์ง‘๋„๊ฐ€ ๋†’๋‹ค
  • ๋Œ€๊ทœ๋ชจ/๋ณต์ฐนํ•œ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜๋‹ค
  • ๋งŒ์•ฝ ์–ด๋–ค ๋„๋ฉ”์ธ์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๊ฑฐ๋‚˜ ์ˆ˜์ •์ด ํ•„์š”ํ•˜๋ฉด ํ•ด๋‹น ๋„๋ฉ”์ธ์˜ ํด๋”๋งŒ ์—ด์–ด ๋ชจ๋“  ๊ด€๋ จ ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค โ†’ ์œ ์ง€๋ณด์ˆ˜์— ์šฉ์ด