์ „์ฒด ๊ธ€

์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

[Project] fetchJoin()์œผ๋กœ JPA N+1 ๋ฌธ์ œ ํ•ด๊ฒฐํ•˜๊ธฐ !

๐Ÿ“Œ QueryDsl์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๊ฐœ๋…๋“ค์€ ์•„๋ž˜ ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. โœ๏ธ N+1 ๋ฌธ์ œ๋ž€? ์—ฐ๊ด€ ๊ด€๊ณ„์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด์Šˆ๋กœ, ์ผ๋Œ€๋‹ค์˜ ์—ฐ๊ด€ ๊ด€๊ณ„๊ฐ€ ์„ค์ •๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•  ๊ฒฝ์šฐ์— ์กฐํšŒ๋œ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜(n)๋งŒํผ ์—ฐ๊ด€ ๊ด€๊ณ„์˜ ์กฐํšŒ ์ฟผ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋กœ ๋ฐœ์ƒํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๊ฒŒ ๋˜๋Š” ๊ฒƒ ๐Ÿ‘‰ ์ฆ‰, 1๋Œ€ N(์ผ๋Œ€๋‹ค)์˜ ์—ฐ๊ด€ ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ…Œ์ด๋ธ”์ด ์žˆ์„ ๊ฒฝ์šฐ์—, 1 ์ชฝ์˜ ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•˜๋ฉด ๊ทธ์— ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ…Œ์ด๋ธ”๋“ค(N)์ด ํ•จ๊ป˜ ์กฐํšŒ๊ฐ€ ๋˜์–ด 1+N๊ฐœ์˜ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค. โœ” N+1 ๋ฌธ์ œ์˜ ์›์ธ JPARepository์— ์ •์˜ํ•œ ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด JPA๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ ๋ถ„์„ํ•ด์„œ JPQL์„ ์ƒ์„ฑํ•˜์—ฌ ์‹คํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. JPQL์€ SQL์„ ์ถ”์ƒํ™”ํ•œ ๊ฐ์ฒด์ง€ํ–ฅ ์ฟผ๋ฆฌ ์–ธ์–ด๋กœ์จ ํŠน์ • SQL์— ์ข…์†๋˜..

์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

QueryDsl์˜ ์‚ฌ์šฉ๊ณผ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๊ธฐ !

โœ๏ธ QueryDsl ์ •์  ํƒ€์ž…(์ปดํŒŒ์ผ ์‹œ ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฒฐ์ •)์„ ์ด์šฉํ•ด์„œ SQL๊ณผ ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ์˜คํ”ˆ์†Œ์Šค ํ”„๋ ˆ์ž„์›Œํฌ SQL, JPQL์„ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๋นŒ๋” API Entity ํด๋ž˜์Šค์™€ ๋งคํ•‘๋˜๋Š” QClass ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฟผ๋ฆฌ ์‹คํ–‰ โœ”๏ธ QClass Entity์™€ ํ˜•ํƒœ๊ฐ€ ๊ฐ™์€ Static Class QueryDsl์€ ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ QClass๋ฅผ ์ƒ์„ฑํ•จ JPAAnnotationProcessor๊ฐ€ ์ปดํŒŒ์ผ ์‹œ์ ์— ์ž‘๋™ํ•ด์„œ @Entity ๋“ฑ์˜ ์• ๋„ˆํ…Œ์ด์…˜์„ ์ฐพ์•„ ํ•ด๋‹น ํŒŒ์ผ๋“ค์„ ๋ถ„์„ํ•ด์„œ QClass๋ฅผ ๋งŒ๋“ฆ ๊ณต์‹ ์‚ฌ์ดํŠธ ๐Ÿ’ก ์™œ QueryDsl์„ ์‚ฌ์šฉํ• ๊นŒ? ์‹ค์ œ๋กœ Query๋ฅผ ์‚ฌ๋žŒ์ด ์งœ๋‹ค๋ณด๋ฉด ์ˆ˜๋งŽ์€ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜์ž‘์—…์œผ๋กœ ์ƒ์„ฑํ•ด์•ผํ•˜๋Š”๋ฐ ์‚ฌ๋žŒ์ด ํ•˜๋‹ค๋ณด๋ฉด ์‹ค์ˆ˜..

์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

[Hibernate] ehcache๋ฅผ ์ด์šฉํ•œ ์บ์‹ฑ

๐Ÿ“Œ ์บ์‹œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๊ฐœ๋…๋“ค์€ ์•„๋ž˜ ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. โœ๏ธ Ehcache Java์˜ ๋Œ€ํ‘œ์ ์ธ ์บ์‹œ ์—”์ง„ ์ค‘์˜ ํ•˜๋‚˜ โœ” ํŠน์ง• ๊ฒฝ๋Ÿ‰์˜ ๋น ๋ฅธ ์บ์‹œ ์—”์ง„ ํ™•์žฅ(scable) โžœ ๋ฉ”๋ชจ๋ฆฌ & ๋””์Šคํฌ ์ €์žฅ ์ง€์›, ๋ฉ€ํ‹ฐ CPU์˜ ๋™์‹œ ์ ‘๊ทผ์— ํŠœ๋‹ ๋ถ„์‚ฐ ์ง€์› โžœ ๋™๊ธฐ/๋น„๋™๊ธฐ ๋ณต์‚ฌ, ํ”ผ์–ด(peer) ์ž๋™ ๋ฐœ๊ฒฌ ๋†’์€ ํ’ˆ์งˆ โžœ Hibernate, Confluence, Spring ๋“ฑ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์œผ๋ฉฐ, Gaia ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ EHCache๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์บ์‹œ ๊ตฌํ˜„ โœ” ์žฅ์  ๋Œ€๊ทœ๋ชจ์˜ ๋™์‹œ์„ฑ ์‹œ์Šคํ…œ์„ ์œ„ํ•ด ์„ค๊ณ„๋˜์–ด ๋น ๋ฅด๊ณ  ๋‹จ์ˆœํ•˜๋ฉฐ, ์•ฑ์„ ์ตœ๋Œ€ํ•œ ๊ฐ€๋ณ๊ฒŒ ์œ ์ง€ํ•˜์—ฌ ์ž‘์€ ๊ณต๊ฐ„์„ ์œ ์ง€ [์ฐธ๊ณ ] https://www.ehcache.org/about/features ์บ์‹œ์— ๋ณด๊ด€๋œ ์ •๋ณด์˜ ๋ณต์‚ฌ๋ณธ์„ ๊ฐ€์ ธ์™€ ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ ํšŸ์ˆ˜ ์ค„์—ฌ์คŒ ๋Œ€์ƒ..

์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

[JPA] ์บ์‹œ(Cache)์˜ ์ถ”์ƒํ™”์™€ ์‚ฌ์šฉ ( @Cacheable, @CachePut, @CacheEvict )

๐Ÿ“Œ ์บ์‹œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๊ฐœ๋…๋“ค์€ ์•„๋ž˜ ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. โœ๏ธ Spring ์บ์‹œ(Cache)์˜ ์ถ”์ƒํ™” ์บ์‹œ๋Š” ํŠธ๋žœ์žญ์…˜๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ AOP๋ฅผ ์ด์šฉํ•˜์—ฌ, ์บ์‹œ ๊ด€๋ จ ๋กœ์ง์„ ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์œผ๋กœ๋ถ€ํ„ฐ ๋ถ„๋ฆฌํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ฉ”์„œ๋“œ์— ์†์‰ฝ๊ฒŒ ์บ์‹œ ๊ธฐ๋Šฅ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜, Spring์€ ์บ์‹œ ๊ตฌํ˜„ ๊ธฐ์ˆ ์— ์ข…์†๋˜์ง€ ์•Š๋„๋ก ์ถ”์ƒํ™”๋œ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ™˜๊ฒฝ์ด ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ์ ์šฉํ•  ์บ์‹œ ๊ธฐ์ˆ ์„ ๋ณ€๊ฒฝํ•ด๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. โœ” ์บ์‹œ ์‚ฌ์šฉ๋ฒ• 1. build.gradle์— ์˜์กด์„ฑ ์ถ”๊ฐ€ implementation 'org.springframework.boot:spring-boot-starter-cache' 2. Application ๋ฒ”์œ„์— @EnableCaching ์• ๋„ˆํ…Œ์ด์…˜ ์ถ”๊ฐ€ 3...

์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

[Project] ํ”„๋กœ์ ํŠธ์—์„œ์˜ 2์ฐจ ์บ์‹œ ๋„์ž… ์ „/ํ›„ ๋น„๊ต!

๐Ÿ“Œ ์บ์‹œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๊ฐœ๋…๋“ค์€ ์•„๋ž˜ ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. ๐Ÿ’ฌ 2์ฐจ ์บ์‹œ ์‚ฌ์šฉ ์ด์œ  ํ”„๋กœ์ ํŠธ์˜ ํ…Œ์ด๋ธ”์ด ๋งŽ์•„์ง€๊ณ  ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ๋งŽ์•„์ง€๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒ/๊ฒ€์ฆ ํ•˜๋Š” ๋ฐ ๋งŽ์€ ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜, ์ด๋Ÿฌํ•œ ์ฟผ๋ฆฌ๋“ค์ด ๋งŽ์•„์ง€๋ฉด์„œ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์„œ๋ฒ„์˜ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ ์ฆ๊ฐ€์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  Hibernate์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” 1์ฐจ ์บ์‹œ๊ฐ€ ์žˆ์ง€๋งŒ, ์ด๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ์™€ ๋™์ผํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋˜๋ฉด ํ•จ๊ป˜ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด 1์ฐจ ์บ์‹œ๋Š” ์บ์‹ฑ ๊ด€์ ์—์„œ ํ…Œ์ดํ„ฐ ๋ฒ ์ด์Šค ์ ‘๊ทผ ํšŸ์ˆ˜๋ฅผ ์ค„์ด๋Š” ์—ญํ• ์„ ํฌ๊ฒŒ ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ด Hibernate 2์ฐจ ์บ์‹œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹จ์œ„์˜ ์บ์‹œ์ด๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋˜๊ธฐ ์ „ ๊นŒ์ง€๋Š” ์ข…๋ฃŒ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋งค๋ฒˆ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒํ•˜์ง€ ..

• JAVA

@NotNull, @NotEmpty, @NotBlank ์˜ ์ฐจ์ด !

ํ”„๋กœ์ ํŠธ์—์„œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ๋˜ ์„ธ ๊ฐ€์ง€ ์• ๋„ˆํ…Œ์ด์…˜๋“ค์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค! ์ž๋ฐ”์—์„œ @NotNull, @NotEmpty, @NotBlank๋Š” ๋ชจ๋‘ ์œ ํšจ์„ฑ ๊ฒ€์ฆ(validation)์„ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์• ๋„ˆํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค. ์ด ์„ธ๊ฐ€์ง€๊ฐ€ ๋น„์Šทํ•˜์ง€๋งŒ ์ฐจ์ด๊ฐ€ ๋ถ„๋ช…ํžˆ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ž˜ ์•Œ์•„์•ผ ์šฉ๋„์— ์•Œ๋งž๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. โœ” @NotNull The annotated element must not be null. Accepts any type. @NotNull ์• ๋„ˆํ…Œ์ด์…˜์€ ๋ง ๊ทธ๋Œ€๋กœ null ๊ฐ’๋งŒ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜, ํ•„๋“œ ๋˜๋Š” ๋ฉ”์„œ๋“œ ๋ฐ˜ํ™˜ ๊ฐ’์ด Null์ธ์ง€ ์ฒดํฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๊ณ , NullPointerException์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ "" / " "์™€ ๊ฐ™์€ ๋นˆ๋ฌธ์ž..

hjjju
๐ŸŒˆ ํ–…์‚