0425 ~ 0501


# 0425 ~ 0501

# 0425 - Given-When-Then Pattern

# Given-When-Then Pattern?

Given-When-Then Pattern์€ BDD(Behaviour-Driven Development) ์ค‘ ํ•˜๋‚˜๋กœ, Test Code ์Šคํƒ€์ผ์„ ํ‘œํ˜„ํ•˜๋Š” ํ•˜๋‚˜์˜ ๋ฐฉ์‹์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

# Given (ํ…Œ์ŠคํŠธ ์ „์˜ ์ƒํƒœ)

  • ํ…Œ์ŠคํŠธ์—์„œ ๊ตฌ์ฒดํ™”ํ•˜๊ณ ์ž ํ•˜๋Š” ํ–‰๋™์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ํ…Œ์ŠคํŠธ ์ƒํƒœ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ถ€๋ถ„
  • ์ฆ‰, ์‹œ๋‚˜๋ฆฌ์˜ค ์ง„ํ–‰์— ํ•„์š”ํ•œ ๊ฐ’์„ ์„ค์ •ํ•˜๊ณ  ํ…Œ์ŠคํŠธ์˜ ์ƒํƒœ๋ฅผ ์„ค์ •ํ•œ๋‹ค

# When (ํ…Œ์ŠคํŠธ ํ–‰์œ„)

  • ๊ตฌ์ฒดํ™”ํ•˜๊ณ ์ž ํ•˜๋Š” ํ–‰๋™
  • ์ฆ‰, ์‹œ๋‚˜๋ฆฌ์˜ค ์ง„ํ–‰ ํ•„์š” ์กฐ๊ฑด ๋ช…์‹œ, ํ…Œ์ŠคํŠธํ•˜๊ณ ์ž ํ•˜๋Š” ํ–‰๋™์„ ๋ช…์‹œํ•œ๋‹ค

# Then (ํ…Œ์ŠคํŠธ ๊ฒ€์ฆ)

  • ํŠน์ • ํ–‰๋™์œผ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ๋ณ€ํ™”์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๋Š” ๋ถ€๋ถ„
  • ์ฆ‰, ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์™„๋ฃŒํ–ˆ์„ ๋•Œ ๋ณด์žฅํ•ด์•ผ ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ช…์‹œํ•˜๊ณ  ์˜ˆ์ƒ๋˜๋Š” ๋ณ€ํ™”๋ฅผ ์„ค๋ช…ํ•œ๋‹ค
@Test
void hasSkill_AlwaysTrue() {
    // given
    given(skills.hasSkill()).willReturn(true);

    // when
    boolean actual = person.hasSkill();

    // then
    assertThat(actual).isTrue();
}

# 0426 - @Modifying

# @Query์ด๋ž€

Spring Data JPA์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ JpaRepository์˜ ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ์™€, ๋ฉ”์„œ๋“œ ๋„ค์ด๋ฐ๋งŒ์„ ํ†ตํ•ด์„œ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ํ•˜์ง€๋งŒ, ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„๋• @Query annotation์„ ์‚ฌ์šฉํ•œ๋‹ค. JPQL ๋ฐ nativeQuery=true ์˜ต์…˜์œผ๋กœ ๋„ค์ดํ‹ฐ๋ธŒ ์ฟผ๋ฆฌ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

# @Modifying์ด๋ž€

@Query Annotation์œผ๋กœ ์ž‘์„ฑ ๋œ ๋ณ€๊ฒฝ, ์‚ญ์ œ ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ํ•„์š”ํ•˜๋‹ค. ์ฆ‰, ์กฐํšŒ ์ฟผ๋ฆฌ๋ฅผ ์ œ์™ธํ•˜๊ณ , ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋Š” INSERT, UPDATE, DELETE, DDL์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. ์ฃผ๋กœ ๋ฒŒํฌ ์—ฐ์‚ฐ์‹œ์— ์‚ฌ์šฉ๋œ๋‹ค.
JPA Entity LifeCycle์„ ๋ฌด์‹œํ•˜๊ณ  ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น annotation์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์˜์†์„ฑ ์ฝ˜ํ…์ŠคํŠธ ๊ด€๋ฆฌ์— ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. ์•ž์œผ๋กœ ์„ค๋ช…ํ•  clearAutomatically, flushAutomatically๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

# ๋ฒŒํฌ์—ฐ์‚ฐ์ด๋ž€

๋ฒŒํฌ ์—ฐ์‚ฐ์ด๋ž€ ๋‹จ๊ฑด UPDATE, DELETE๋ฅผ ์ œ์™ธํ•œ ๋‹ค๊ฑด์˜ UPDATE, DELETE ์—ฐ์‚ฐ์„ ํ•˜๋‚˜์˜ ์ฟผ๋ฆฌ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. JPA์—์„œ ๋‹จ๊ฑด UPDATE ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” Dirty Checking์„ ํ†ตํ•ด์„œ ์ˆ˜ํ–‰๋˜๊ฑฐ๋‚˜ save()๋กœ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. DELETE์˜ ๊ฒฝ์šฐ์—๋Š” ๋‹ค๊ฑด, ๋‹จ๊ฑด ๋ชจ๋‘ ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ๋กœ ์ œ๊ณต๋œ๋‹ค.
@Query์— ๋ฒŒํฌ ์—ฐ์‚ฐ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , @Modifying์„ ๋ถ™์ด์ง€ ์•Š์œผ๋ฉด, InvalidDataAccessApiUsage exception์ด ๋ฐœ์ƒํ•œ๋‹ค.

# clearAutomatically

์ด Attribute๋Š” @Modifying์ด ๋ถ™์€ ํ•ด๋‹น ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ง ํ›„, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ clear ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ง€์ •ํ•˜๋Š” Attribute์ด๋‹ค. defalut ๊ฐ’์€ false๋‹ค. true์‹œ ๋ฒŒํฌ ์—ฐ์‚ฐ ์ง ํ›„ ์ž๋™์œผ๋กœ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ํด๋ฆฌ์–ด ํ•ด์ค€๋‹ค.


# 0429 - JPA - OSIV

# OSIV(Open Sessio In View)

OSIV๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๋ทฐ๊นŒ์ง€ ์—ด์–ด๋‘๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์œ ์ง€๋˜๋ฉด ์—”ํ‹ฐํ‹ฐ๋„ ์˜์† ์ƒํƒœ๋กœ ์œ ์ง€๋œ๋‹ค. ๋ทฐ๊นŒ์ง€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์‚ด์•„์žˆ๋‹ค๋ฉด ๋ทฐ์—์„œ๋„ ์ง€์—ฐ ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

JPA์—์„œ๋Š” OEIV(Open EntityManage In View), ํ•˜์ด๋ฒ„๋„ค์ดํŠธ์—์„  OSIV(Open Session In View)๋ผ๊ณ  ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๊ด€๋ก€์ƒ ๋‘˜ ๋‹ค OSIV๋กœ ๋ถ€๋ฅธ๋‹ค.

# OSIV ๋™์ž‘ ์›๋ฆฌ

OSIV์˜ ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•ด์„œ Spring Framework๊ฐ€ ์ œ๊ณตํ•˜๋Š” OSIV๋ฅผ ํ†ตํ•ด ๋ณด๋ฉด, ์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” OSIV ํด๋ž˜์Šค๋Š” ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ์—์„œ ์ ์šฉํ• ์ง€ ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ์—์„œ ์ ์šฉํ• ์ง€์— ๋”ฐ๋ผ ์›ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์„ ํƒํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ œ๊ณตํ•˜๋Š” OSIV๋Š” ๋น„์ง€๋‹ˆ์Šค ๊ณ„์ธต์—์„œ ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•˜๋Š” OSIV๋‹ค. ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ ์‹œ์ ์—์„œ ์ƒ์„ฑ์ด ๋˜์ง€๋งŒ, ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ํŠธ๋žœ์žญ์…˜์€ ๋น„์ฆˆ๋‹ˆ์Šค ๊ณ„์ธต์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํŠธ๋žœ์žญ์…˜์ด ์ผ์–ด๋‚œ๋‹ค.

image

  • spring.jpa.open-in-view : true ๊ธฐ๋ณธ๊ฐ’

Spring Boot JPA์˜์กด์„ฑ์„ ์ฃผ์ž… ๋ฐ›์•„ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•  ๊ฒฝ์šฐ spring.jpa.open-in-view์˜ ๊ธฐ๋ณธ๊ฐ’์ธ true๋กœ ์ง€์ •๋˜์–ด ์žˆ์–ด OSIV๊ฐ€ ์ ์šฉ๋œ ์ƒํƒœ๋กœ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ตฌ์„ฑ๋œ๋‹ค.

๋™์ž‘์›๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ๋‚˜, ์Šคํ”„๋ง์ธํ„ฐ์…‰ํ„ฐ์—์„œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ๋‹จ ์ด ์‹œ์ ์—์„œ ํŠธ๋žœ์žญ์…˜์€ ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ @Transactional๋กœ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•  ๋•Œ 1๋ฒˆ์—์„œ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ฐพ์•„์™€์„œ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•œ๋‹ค.
  • ์„œ๋น„์Šค ๊ณ„์ธต์ด ๋๋‚˜๋ฉด ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•˜๊ณ  ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ํ”Œ๋Ÿฌ์‹œํ•œ๋‹ค. ์ด ์‹œ์ ์— ํŠธ๋žœ์žญ์…˜์€ ๋๋‚ด์ง€๋งŒ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ์ข…๋ฃŒ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ทฐ๊นŒ์ง€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์œ ์ง€๋˜๋ฏ€๋กœ ์กฐํšŒํ•œ ์—”ํ‹ฐํ‹ฐ๋Š” ์˜์† ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.
  • ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ๋‚˜, ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ๋กœ ์š”์ฒญ์ด ๋Œ์•„์˜ค๋ฉด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค. ์ด๋•Œ ํ”Œ๋Ÿฌ์‹œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์ข…๋ฃŒํ•œ๋‹ค.

์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๋ฉด ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ทฐ์—๋Š” ํŠธ๋žœ์žญ์…˜์ด ์œ ์ง€๋˜์ง€ ์•Š๋Š” ์ƒํƒœ์ด๋‹ค. ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋‹จ์ˆœํžˆ ์กฐํšŒ๋งŒ ํ•  ๋•Œ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์—†์–ด๋„ ๋™์ž‘ํ•˜๋Š”๋ฐ, ์ด๊ฒƒ์„ ํŠธ๋žœ์žญ์…˜ ์—†์ด ์ฝ๊ธฐ(Nontransactional reads)๋ผ ํ•œ๋‹ค. ํ•˜์—ฌ ๋งŒ์•ฝ ํ”„๋ก์‹œ๋ฅผ ๋ทฐ ๋ Œ๋”๋งํ•˜๋Š” ๊ณผ์ •์— ์ดˆ๊ธฐํ™”(Lazy loading)๊ฐ€ ์ผ์–ด๋‚˜๊ฒŒ ๋˜์–ด๋„ ์กฐํšŒ ๊ธฐ๋Šฅ์ด๋ฏ€๋กœ ํŠธ๋žœ์žญ์…˜์ด ์—†์ด ์ฝ๊ธฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„ ์•ˆ์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„ ๋ฐ–์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒ๋งŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์„ ํŠธ๋žœ์žญ์…˜ ์—†์ด ์ฝ๊ธฐ(Nontransactional reads)๋ผ ํ•œ๋‹ค.

๋งŒ์•ฝ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„ ๋ฐ–์ธ ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ทฐ์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ๋„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋ณ€๊ฒฝ ๊ฐ์ง€์— ์˜ํ•œ ๋ฐ์ดํ„ฐ ์ˆ˜์ •์ด ๋‹ค์Œ 2๊ฐ€์ง€ ์ด์œ ๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜ํ•˜๋ ค๋ฉด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ํ”Œ๋Ÿฌ์‹œ(flush)ํ•ด์•ผ ํ•œ๋‹ค. ์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” OSIV๋Š” ์š”์ฒญ์ด ๋๋‚˜๋ฉด ํ”Œ๋Ÿฌ์‹œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  em.close()๋กœ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋งŒ ์ข…๋ฃŒ์‹œ์ผœ ๋ฒ„๋ฆฐ๋‹ค.
  • ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ณ„์ธต์—์„œ em.flush()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ•์ œ๋กœ ํ”Œ๋Ÿฌ์‹œํ•ด๋„ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„ ๋ฐ–์ด๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜ˆ์™ธ๊ฐ€ ์ผ์–ด๋‚œ๋‹ค. (javax.persistence.TransactionRequiredException)

# OSIV ์‚ฌ์šฉ์‹œ ์ฃผ์˜์ 

2021-01-18 21:54:44.750 WARN 36808 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

spring.jpa.open-in-view์˜ ๊ฐ’์„ ๊ธฐ๋ณธ๊ฐ’(true)์œผ๋กœ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ๋™ํ•˜๋ฉด, ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ์ ์— ์œ„์™€ ๊ฐ™์€ warn ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๊ฒŒ ๋œ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ์œ„ ๋™์ž‘ ๋ฐฉ์‹์ฒ˜๋Ÿผ ํ”„๋ก์‹œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ž‘์—…์„ Service ๊ณ„์ธต์—์„œ ๋๋‚ด์ง€ ์•Š๊ณ ๋„ ๋ Œ๋”๋ง ์‹œ ์ž๋™์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ์žฅ์ ์ด ์žˆ๋Š” OSIV์ „๋žต์— ์™œ ๊ฒฝ๊ณ ๋ฅผ ์ค„๊นŒ?

OSIV ์ „๋žต์€ ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘์ฒ˜๋Ÿผ ์ตœ์ดˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜ ์‹œ์ž‘ ์‹œ์ ์—์„œ API ์‘๋‹ต์ด ๋๋‚  ๋•Œ ๊นŒ์ง€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์„ ์œ ์ง€ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ View Template์ด๋‚˜ API ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ง€์—ฐ ๋กœ๋”ฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
์ง€์—ฐ ๋กœ๋”ฉ์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์‚ด์•„์žˆ์–ด์•ผ ๊ฐ€๋Šฅํ•˜๊ณ , ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์„ ์œ ์ง€ํ•œ๋‹ค. ์ด๊ฒƒ ์ž์ฒด๊ฐ€ ํฐ ์žฅ์ ์ด๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ด์ „๋žต์€ ๋„ˆ๋ฌด ์˜ค๋žœ์‹œ๊ฐ„๋™์•ˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์‹œ๊ฐ„ ํŠธ๋ž˜ํ”ฝ์ด ์ค‘์š”ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์ปค๋„ฅ์…˜์ด ๋ชจ์ž๋ž„ ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ ๊ฒฐ๊ตญ ์žฅ์• ๋กœ ์ด์–ด์ง„๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์™ธ๋ถ€ API๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์™ธ๋ถ€ API ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋งŒํผ ์ปค๋„ฅ์…˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ๋ชปํ•˜๊ณ , ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค. -> OISV์˜ ์น˜๋ช…์ ์ธ ๋‹จ์ , ์ปค๋„ฅ์…˜์„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ 1:1๋กœ ๊ณ„์† ๋ฌผ๊ณ  ์žˆ๋‹ค.

[ OSIV OFF ] image

  • spring.jpa.open-in-view: false (OSIV ์ข…๋ฃŒ)

OSIV๋ฅผ ๋„๋ฉด ํŠธ๋žœ์žญ์…˜์„ ์ข…๋ฃŒํ•  ๋•Œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ซ๊ณ , ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜๋„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ปค๋„ฅ์…˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚ญ๋น„ํ•˜์ง€ ์•Š๋Š”๋‹ค. OSIV๋ฅผ ๋„๋ฉด ๋ชจ๋“  ์ง€์—ฐ๋กœ๋”ฉ์„ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ง€๊ธˆ๊นŒ์ง€ ์ž‘์„ฑํ•œ ๋งŽ์€ ์ง€์—ฐ ๋กœ๋”ฉ ์ฝ”๋“œ๋ฅผ ํŠธ๋žœ์žญ์…˜์•ˆ์œผ๋กœ ๋„ฃ์–ด์•ผ ํ•˜๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  view template์—์„œ ์ง€์—ฐ๋กœ๋”ฉ์ด ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๊ธฐ ์ „์— ์ง€์—ฐ ๋กœ๋”ฉ์„ ๊ฐ•์ œ๋กœ ํ˜ธ์ถœํ•ด ๋‘์–ด์•ผ ํ•œ๋‹ค.

# ์ปค๋งจ๋“œ์™€ ์ฟผ๋ฆฌ ๋ถ„๋ฆฌ

์‹ค๋ฌด์—์„œ OSIV๋ฅผ ๋ˆ ์ƒํƒœ๋กœ ๋ณต์žก์„ฑ์„ ๊ด€๋ฆฌํ•˜๋Š” ์ข…์€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ๋ฐ”๋กœ Command์™€ Query๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

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

์˜ˆ)
OrderService

  • OrderService : ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
  • OrderQueryService : ํ™”๋ฉด์ด๋‚˜ API์— ๋งž์ถ˜ ์„œ๋น„์Šค (์ฃผ๋กœ ์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜ ์‚ฌ์šฉ)

๋ณดํ†ต ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ํŠธ๋žœ์žญ์…˜์„ ์œ ์ง€ํ•œ๋‹ค. ๋‘ ์„œ๋น„์Šค ๋ชจ๋‘ ํŠธ๋žœ์žญ์…˜์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์ง€์—ฐ ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

# OSIV ์ •๋ฆฌ

ํŠน์ง•

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

๋‹จ์ 

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ DB ์ปค๋„ฅ์…˜์€ 1:1๋กœ ๋ฌผ๊ณ ์žˆ๋Š” ๊ด€๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๋กœ์ง๊นŒ์ง€ DB ์ปค๋„ฅ์…˜ ์ž์›์„ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋จ.
  • OSIV๋ฅผ ์ ์šฉํ•˜๋ฉด ๊ฐ™์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ๊ณต์œ ํ•˜๊ฒŒ๋  ์ˆ˜๋„ ์žˆ๋‹ค.
  • ํ”„๋ ˆ์  ํ…Œ์ด์…˜์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ˆ˜์ •๋  ์ˆ˜ ์žˆ๋‹ค.
  • ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ณ„์ธต์—์„œ ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ ์ง€์—ฐ ๋กœ๋”ฉ์— ์˜ํ•ด SQL์ด ์‹คํ–‰๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์„ฑ๋Šฅ ํŠœ๋‹์‹œ์— ํ™•์ธํ•ด์•ผ ํ•  ๋ถ€๋ถ„์ด ๋„“์–ด์ง„๋‹ค.

# 0430 - DAU, PU, PV

# DAU / WAU / MAU

1์ผ, 1์ฃผ, 1๋‹ฌ ๋™์•ˆ ํ™œ์„ฑ ์‚ฌ์šฉ์ž(Active User)์˜ ์ˆ˜๋ฅผ ์˜๋ฏธ

# DAU (Daily)

  • ํ•˜๋ฃจ ๋™์•ˆ ๋ฐฉ๋ฌธํ•œ ์ˆœ์ˆ˜ ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์ง‘๊ณ„
  • ๊ฒŒ์ž„, ๋ฉ”์‹ ์ € ๋“ฑ ์‚ฌ์šฉ๋นˆ๋„๊ฐ€ ๋†’์€ ์•ฑ์˜ ์ฃผ์š” ์ง€ํ‘œ๋กœ ํ™œ์šฉ๋จ
  • ์„œ๋ฒ„ ๋ถ€ํ•˜๋ฅผ ๋น„๋กฏํ•œ ํŠธ๋ž˜ํ”ฝ ๊ด€๋ จ ๋ณ€๋™๋น„ ์ถ”์ • ๋ฐ ์ตœ์ ํ™”์™€ ์—ฐ๊ด€์ด ๊นŠ์Œ

# WAU (Weekly Active User)

  • ์ผ์ฃผ์ผ(7์ผ) ๋™์•ˆ ๋ฐฉ๋ฌธํ•œ ์ˆœ์ˆ˜ ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์ง‘๊ณ„
  • ๋งค์ผ ์ ‘์†ํ•  ํ•„์š” ์—†๋Š” ๋ชจ๋ฐ”์ผ ์€ํ–‰๊ณผ ๊ฐ™์€ ์•ฑ์—์„œ ์ฃผ๋กœ ํ™œ์šฉ๋˜๋Š” ์ง€ํ‘œ

# MAU (Monthly Active User)

  • ์›” ๊ฐ„(30์ผ) ๋ฐฉ๋ฌธํ•œ ์ˆœ์ˆ˜ ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์ง‘๊ณ„
  • ์ˆ˜์น˜๊ฐ€ ํฌ๊ธฐ ๋•Œ๋ฌธ์— ๋น„์ฆˆ๋‹ˆ์Šค๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฐ์— ์ฃผ๋กœ ์ธ์šฉ๋จ
  • ํ•˜์ง€๋งŒ ์‹ค์ œ์ ์ธ ์œ ์ €์˜ ํ™œ์„ฑํ™” ์ •๋„๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์šด ๋‹จ์ ์ด ์žˆ์Œ

# PU / ARPU / ARPPU

# PU (Paying Users)

  • ์œ ๋ฃŒ ์œ ์ € ์ˆ˜ (๊ฒฐ์ œํ•œ ์œ ์ € ์ˆ˜)

# ARPU (Average Revenue Per Users)

  • ์œ ์ €๋ณ„ ํ‰๊ท  ๋งค์ถœ
  • ARPU = ์ด๋งค์ถœ/์ด ์œ ์ €์ˆ˜
  • ์‰ฝ๊ฒŒ ๋งํ•ด '๊ฐ๋‹จ๊ฐ€', ํ•œ ๋ช…์˜ ์œ ์ €๊ฐ€ ํ‰๊ท  ์–ผ๋งˆ๋ฅผ ์ง€์ถœํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ์ง€ํ‘œ

# ARPPU (Average Revenue Per Paying Users)

  • ์œ ๋ฃŒ ์œ ์ €๋ณ„ ํ‰๊ท  ๋งค์ถœ
  • ARPPU = ์ด๋งค์ถœ/์ด ์œ ๋ฃŒ ์„œ๋น„์Šค ๊ตฌ๋งค ์œ ์ €
  • ์‰ฝ๊ฒŒ ๋งํ•ด '๊ฒฐ์ œ์ž ๊ฐ๋‹จ๊ฐ€', ํ•œ ๋ช…์˜ ์œ ๋กœ ์œ ์ €๊ฐ€ ํ‰๊ท  ์–ผ๋งˆ๋ฅผ ์ง€์ถœํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ์ง€ํ‘œ

# Entrance, PV, UV

# Entrance (๋ฐฉ๋ฌธ ์ˆ˜)

  • ์›น ์‚ฌ์ดํŠธ ๋ฐฉ๋ฌธ์—์„œ ์ดํƒˆ๊นŒ์ง€ ์ˆ˜ํ–‰ํ•˜๋Š” ํ†ตํ•ฉ ๋‹จ์œ„

# PV (Page View)

  • ์‚ฌ์ดํŠธ ์•ˆ์—์„œ ํŽ˜์ด์ง€๋ฅผ ์กฐํšŒํ•œ ํšŸ์ˆ˜

ex) 1๋ช…์ด ๋ธ”๋กœ๊ทธ ๊ธ€ 2๊ฐœ๋ฅผ ์ฝ๋Š”๋‹ค๋ฉด?
= PV๋Š” 2๋กœ ์ง‘๊ณ„

# UV (Unique Visitors)

  • ์ˆœ๋ฐฉ๋ฌธ์ž. ์ตœ์ดˆ ์„ธ์…˜์„ ์ผ์œผํ‚จ ๋ฐฉ๋ฌธ์ž
  • ์›นํŽ˜์ด์ง€์— ๋ฐฉ๋ฌธํ•œ ์‚ฌ๋žŒ์˜ ์ˆ˜ ์˜๋ฏธ
  • ์ผ๋ฐ˜์ ์œผ๋กœ IP๋ฅผ ๊ธฐ์ค€์œผ๋กœ, 30๋ถ„ ๋‹จ์œ„๋กœ ์ชผ๊ฐœ์„œ ๊ณ„์‚ฐ

ex) 1๋ช…์ด ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์—ฌ๋Ÿฌ๋ฒˆ ๋ณธ๋‹ค๋ฉด?
= UV๋Š” 1๋กœ ์ง‘๊ณ„

ex) 1๋ช…์ด ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ฝ๊ณ , 30๋ถ„ ๋’ค์— ํ•œ ๋ฒˆ ๋” ๋ณธ๋‹ค๋ฉด?
= UV๋Š” 2๋กœ ์ง‘๊ณ„


# 0501 - Spring Bean vs Static method ์–ธ์ œ ์–ด๋Š๊ฑธ ์‚ฌ์šฉํ•ด์•ผํ• ๊นŒ?

๋จผ์ € ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” static ํ•จ์ˆ˜ ๋ชจ์Œ class๋ž€ Apache Commons Lang StringUtils (opens new window)์ฒ˜๋Ÿผ ์ˆœ์ „ํžˆ static ํ•จ์ˆ˜๋งŒ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

static ํ•จ์ˆ˜ ๋ชจ์Œ ํด๋ž˜์Šค์˜ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ์ธ์ž๊ฐ€ ๋™์ผํ•  ๊ฒฝ์šฐ ํ•ญ์ƒ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•ด์•ผ ํ•œ๋‹ค. ์ด๊ทœ์น™์„ ์ง€ํ‚ฌ ์ˆ˜ ์—†์œผ๋ฉด POJO Bean์œผ๋กœ ๋งŒ๋“ค๋ผ.

์ด๊ฒƒ์ด ์ด๋ค„์ง€๋ ค๋ฉด ํ•จ์ˆ˜ ์•ˆ์—์„œ๋Š” ์™ธ๋ถ€ ์ž์›(Resource)์— ๋Œ€ํ•ด ํ•˜๋‚˜๋„ ์˜์กดํ•˜๋ฉด ์•ˆ๋œ๋‹ค๋Š” ์„ ๊ฒฐ ์กฐ๊ฑด์„ ์ถฉ์กฑํ•ด์•ผ ํ•œ๋‹ค. ์™ธ๋ถ€ ์ž์›์€ ๊ทธ ์‹คํ–‰ ๊ฒฐ๊ณผ์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด์— ๊ฐ€์žฅ ์ž˜ ๋“ค์–ด๋งž๋Š” ์˜ˆ๋Š” StringUtils (opens new window), CollectionUtils (opens new window) ๊ฐ™์€ ๊ฒƒ๋“ค์ด๋‹ค.

Last update: September 13, 2022 21:44
Contributors: ahnjs