์ฑ„๋„ํ†ก ์•„์ด์ฝ˜

[Lv2] ํ˜„์—… ๊ฐœ๋ฐœ์ž์˜ JPA ์™„์ „ ์ •๋ณต - ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ถ€ํ„ฐ ์‹ค๋ฌด ํŒจํ„ด๊นŒ์ง€

JdbcTemplate์œผ๋กœ SQL ์งœ๋ณธ ์  ์žˆ์œผ์‹œ์ฃ ? ์ปฌ๋Ÿผ ํ•˜๋‚˜ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค SQL์ด๋ž‘ RowMapper ๋™์‹œ์— ๊ณ ์น˜๋А๋ผ ํ•œ์ˆจ ์‰ฌ์—ˆ๋˜ ๊ฒฝํ—˜, ๋‹ค๋“ค ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. ์ด ๊ฐ•์˜๋Š” ๊ทธ ๊ณ ํ†ต์—์„œ ์ถœ๋ฐœํ•ฉ๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ JDBC๋กœ SELECT ํ•˜๋‚˜ ํ•˜๋ฉด 35์ค„์ž…๋‹ˆ๋‹ค. Connection ์—ด๊ณ , PreparedStatement ๋งŒ๋“ค๊ณ , ResultSet ๋Œ๋ฆฌ๊ณ , close() ํ•˜๋‚˜ ๋น ๋œจ๋ฆฌ๋ฉด ์„œ๋ฒ„๊ฐ€ ๋‹ค์šด๋ฉ๋‹ˆ๋‹ค. ์ด ์ง€์˜ฅ์„ ์ง์ ‘ ํƒ€์ดํ•‘ํ•œ ๋’ค์— JPA์˜ save() ํ•œ ์ค„์„ ๋งŒ๋‚˜๋ฉด, "์ด๋ž˜์„œ JPA๋ฅผ ์“ฐ๋Š”๊ตฌ๋‚˜"๊ฐ€ ๋จธ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ ์†์—์„œ ์ฒด๊ฐ๋ฉ๋‹ˆ๋‹ค.

13๋ช… ์ด ์ˆ˜๊ฐ•ํ•˜๊ณ  ์žˆ์–ด์š”.

๋‚œ์ด๋„ ์ดˆ๊ธ‰

์ˆ˜๊ฐ•๊ธฐํ•œ ๋ฌด์ œํ•œ

์‹ค์Šต ์ค‘์‹ฌ
์‹ค์Šต ์ค‘์‹ฌ
๋ฐฑ์—”๋“œ์ดํ•ดํ•˜๊ธฐ
๋ฐฑ์—”๋“œ์ดํ•ดํ•˜๊ธฐ
์ทจ์—…์ค€๋น„
์ทจ์—…์ค€๋น„
๊ฐœ๋ฐœ์ž์ทจ์—…
๊ฐœ๋ฐœ์ž์ทจ์—…
์‹ค์Šต ์ค‘์‹ฌ
์‹ค์Šต ์ค‘์‹ฌ
๋ฐฑ์—”๋“œ์ดํ•ดํ•˜๊ธฐ
๋ฐฑ์—”๋“œ์ดํ•ดํ•˜๊ธฐ
์ทจ์—…์ค€๋น„
์ทจ์—…์ค€๋น„
๊ฐœ๋ฐœ์ž์ทจ์—…
๊ฐœ๋ฐœ์ž์ทจ์—…

์ˆ˜๊ฐ• ํ›„ ์ด๋Ÿฐ๊ฑธ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”

  • 1์ฐจ ์บ์‹œ, ๋ณ€๊ฒฝ ๊ฐ์ง€, ์“ฐ๊ธฐ ์ง€์—ฐ๊นŒ์ง€ ๊ฒฝํ—˜ ๊ธฐ๋ฐ˜์œผ๋กœ ์ˆ ์ˆ  ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ

  • JDBC 35์ค„์˜ ๊ณ ํ†ต์„ ์ง์ ‘ ๊ฒช๊ณ  ๋‚˜์„œ JPA๊ฐ€ ์™œ ํ•„์š”ํ•œ์ง€ ์ฒด๊ฐํ•œ ๊ฒฝํ—˜

  • N+1 ๋ฌธ์ œ๊ฐ€ ํ„ฐ์กŒ์„ ๋•Œ ๋กœ๊ทธ๋ฅผ ๋ณด๊ณ  ์›์ธ์„ ์ฐพ๊ณ , Fetch Join / @EntityGraph / @BatchSize ์ค‘ ์ƒํ™ฉ์— ๋งž๋Š” ํ•ด๊ฒฐ๋ฒ•์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค๋ฌด ๋””๋ฒ„๊น… ๋Šฅ๋ ฅ

  • QueryDSL์˜ BooleanExpression์œผ๋กœ if๋ฌธ ์ŠคํŒŒ๊ฒŒํ‹ฐ ์—†์ด ๊น”๋”ํ•œ ๋™์  ์ฟผ๋ฆฌ๋ฅผ ์„ค๊ณ„ํ•˜๊ณ , Custom Repository ํŒจํ„ด์œผ๋กœ JPA์™€ QueryDSL์„ ์‹ค๋ฌด ํ‘œ์ค€ ๊ตฌ์กฐ๋กœ ํ†ตํ•ฉํ•˜๋Š” ์—ญ๋Ÿ‰

  • ์—”ํ‹ฐํ‹ฐ ์„ค๊ณ„๋ถ€ํ„ฐ ์ƒ์†๊ด€๊ณ„ ๋งคํ•‘, BaseEntity(Auditing), ์ž„๋ฒ ๋””๋“œ ํƒ€์ž…๊นŒ์ง€ โ€” ์‹ค๋ฌด ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ "ํ…Œ์ด๋ธ” ์„ค๊ณ„ ์–ด๋–ป๊ฒŒ ํ•˜์ง€?"๊ฐ€ ์•„๋‹ˆ๋ผ "์ด ํŒจํ„ด์œผ๋กœ ๊ฐ€์ž"๊ณ  ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ์„ค๊ณ„ ๊ฐ๊ฐ

์Šคํ”„๋ง, ์ด๋ ‡๊ฒŒ ๋ฐฐ์šฐ๋ฉด ๋ฉด์ ‘์—์„œ ๋–จ์–ด์ง‘๋‹ˆ๋‹ค

Lv.1์—์„œ ์Šคํ”„๋ง ๋ถ€ํŠธ๋กœ API ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

JdbcTemplate์œผ๋กœ SQL ์งœ๊ณ , RowMapper๋กœ ๊ฒฐ๊ณผ ๋งคํ•‘ํ•˜๊ณ ... ์˜ค, CRUD ๋Œ์•„๊ฐ€๋„ค!

๊ทผ๋ฐ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์ด๋Ÿฐ ์ƒ๊ฐ์ด ๋“ญ๋‹ˆ๋‹ค.

"SQL์„ ์™œ ์ž๋ฐ” ์ฝ”๋“œ ์•ˆ์— ๋ฌธ์ž์—ด๋กœ ์จ์•ผ ํ•˜์ง€?"

"์ปฌ๋Ÿผ ํ•˜๋‚˜ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค SQL์ด๋ž‘ RowMapper๋ฅผ ๋‹ค ๊ณ ์ณ์•ผ ํ•˜๋„ค..."

"์ด๊ฑฐ ํ…Œ์ด๋ธ” 10๊ฐœ ๋˜๋ฉด ์–ด๋–กํ•˜์ง€?"

๊ทธ๋ฆฌ๊ณ  ๋ฉด์ ‘์—์„œ ์ด๋ ‡๊ฒŒ ๋ฌผ์–ด๋ด…๋‹ˆ๋‹ค.

"DB ์ €์žฅํ•  ๋•Œ JdbcTemplate ๋ง๊ณ  ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์—†๋‚˜์š”?"

"์Œ... JPA๋ผ๋Š” ๊ฒŒ ์žˆ๋‹ค๊ณ  ๋“ค์—ˆ๋Š”๋ฐ... ์†”์งํžˆ ์•ˆ ์จ๋ด์„œ..."

๋–จ์–ด์ง‘๋‹ˆ๋‹ค.

"JPA์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๋ญ”๊ฐ€์š”?"

"... ๋„ค?"

SQL์„ ์ง์ ‘ ์งœ๋ณธ ๊ฒฝํ—˜์€ ์žˆ๋Š”๋ฐ, ๊ทธ ๊ณ ํ†ต์„ ํ•ด๊ฒฐํ•˜๋Š” ๊ธฐ์ˆ ์€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.


๋Œ€๋ถ€๋ถ„์˜ JPA ๊ฐ•์˜๊ฐ€ "์–ด๋–ป๊ฒŒ ์“ฐ๋Š”์ง€"๋งŒ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค.

"JPA๋Š” ORM์ž…๋‹ˆ๋‹ค. @Entity ๋ถ™์ด๊ณ  save() ์“ฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค."

๋”ฐ๋ผํ•˜๋ฉด ๋Œ์•„๊ฐ€์š”. ๊ทผ๋ฐ ๋ฉด์ ‘๊ด€์€ "์™œ"๋ฅผ ๋ฌป์Šต๋‹ˆ๋‹ค.

"JPA๋ฅผ ์™œ ์“ฐ๋‚˜์š”?"

"์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์„ค๋ช…ํ•ด๋ณด์„ธ์š”."

"N+1 ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•˜์…จ๋‚˜์š”?"

How๋งŒ ๋ฐฐ์šด ์‚ฌ๋žŒ์€ ์ด๋ ‡๊ฒŒ ๋‹ตํ•ฉ๋‹ˆ๋‹ค.

"JPA๋Š”... ORM์ด๊ณ ์š”... save() ์“ฐ๋ฉด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค..."

๊ทธ๊ฒŒ ๋์ด์—์š”. ๋” ํ•  ๋ง์ด ์—†์–ด์š”.

JPA ์—†์ด ํ•ด๋ณธ ์ ์ด ์—†์œผ๋‹ˆ๊นŒ์š”. JDBC๋กœ 35์ค„ ์งœ๋ณธ ์ ์ด ์—†์œผ๋‹ˆ๊นŒ, JPA๊ฐ€ ์™œ ํ•„์š”ํ•œ์ง€ ๋ชจ๋ฅด๋Š” ๊ฑฐ์˜ˆ์š”.


๊ทธ๋ž˜์„œ ์ด ๊ฐ•์˜๋Š” "๊ณ ํ†ต"์„ ๋จผ์ € ์ค๋‹ˆ๋‹ค

JPA ์ œ๋Œ€๋กœ ๋ฐฐ์šฐ๋ ค๋ฉด์š”, save() ๋จผ์ € ๋ฐฐ์šฐ๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. JDBC 35์ค„์˜ ๊ณ ํ†ต์„ ๋จผ์ € ๊ฒช์–ด์•ผ ํ•ด์š”.

์ˆœ์ˆ˜ JDBC๋กœ SELECT ํ•˜๋‚˜ ํ•˜๋ฉด 35์ค„์ž…๋‹ˆ๋‹ค. Connection ์—ด๊ณ , PreparedStatement ๋งŒ๋“ค๊ณ , ResultSet ๋Œ๋ฆฌ๊ณ , close() ์•ˆ ํ•˜๋ฉด ์„œ๋ฒ„ ๋‹ค์šด... ์ด๊ฑฐ ์ง์ ‘ ํƒ€์ดํ•‘ํ•˜๋Š” ๊ฑฐ์˜ˆ์š”.

์ด ๊ณ ํ†ต์„ ๊ฒช๊ณ  ๋‚˜์„œ JPA์˜ save() ํ•œ ์ค„์„ ๋ณด๋ฉด์š”? ์งœ๋ฆฟํ•ฉ๋‹ˆ๋‹ค.

์ด ์ˆœ๊ฐ„, ์ด๋ ‡๊ฒŒ ๋ฉ๋‹ˆ๋‹ค: "์•„... ์ด๋ž˜์„œ JPA๋ฅผ ์“ฐ๋Š”๊ตฌ๋‚˜. ์ด๋ž˜์„œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•œ ๊ฑฐ๊ตฌ๋‚˜."

N+1๋„ ๋˜‘๊ฐ™์•„์š”. ํšŒ์› 10๋ช…์„ ์กฐํšŒํ–ˆ๋Š”๋ฐ ์ฟผ๋ฆฌ๊ฐ€ 11๊ฐœ ๋‚˜๊ฐ€๋Š” ์ง€์˜ฅ์„ ์ง์ ‘ ๊ฒช๊ณ  ๋‚˜์„œ, Fetch Join ํ•œ ์ค„๋กœ 1๊ฐœ๋กœ ์ค„์–ด๋“œ๋Š” ๊ฑธ ๋ณด๋ฉด, ๊ทธ ์›๋ฆฌ๊ฐ€ ๋ผˆ์— ์ƒˆ๊ฒจ์ง‘๋‹ˆ๋‹ค.

์ด "๊ณ ํ†ต โ†’ ๊ตฌ์›" ๊ฒฝํ—˜์ด ์—ฌ๋Ÿฌ๋ถ„์„ "์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐœ๋ฐœ์ž"๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

5์ฃผ ๋’ค, ์—ฌ๋Ÿฌ๋ถ„์€ ๋ฉด์ ‘์žฅ์—์„œ ์ด๋ ‡๊ฒŒ ๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

โŒ (์ผ๋ฐ˜์ ์ธ ๋‹ต๋ณ€) "JPA๋Š” ORM ๊ธฐ์ˆ ์ด๋ผ์„œ ํŽธ๋ฆฌํ•ด์„œ ์”๋‹ˆ๋‹ค."

โญ• (๊ฒฝํ—˜ ๊ธฐ๋ฐ˜ ๋‹ต๋ณ€) "์ œ๊ฐ€ ์ง์ ‘ JDBC๋กœ ๊ฐœ๋ฐœํ•ด๋ดค๋Š”๋ฐ์š”, SQL์„ ๋งค๋ฒˆ ์ž‘์„ฑํ•˜๋Š” ๋ฐ˜๋ณต ์ž‘์—…๋„ ๋ฌธ์ œ์ง€๋งŒ, ๋ฌด์—‡๋ณด๋‹ค ๊ฐ์ฒด ์ง€ํ–ฅ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด DB์— ์ €์žฅํ•  ๋•Œ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒŒ ํž˜๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ JPA์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ 1์ฐจ ์บ์‹œ์™€ ๋ณ€๊ฒฝ ๊ฐ์ง€๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์ฃผ๋”๊ตฐ์š”."

์ด๋ ‡๊ฒŒ ๋‹ตํ•˜๋ฉด ๋ฉด์ ‘๊ด€๋„ '์•„, ์ด ์นœ๊ตฌ๋Š” ์ง์ ‘ ๊ฒช์–ด๋ดค๊ตฌ๋‚˜' ํ•˜๊ณ  ๋А๋‚„ ์ˆ˜ ์žˆ์–ด์š”.

โœ… ์ด๋Ÿฐ ๋‚ด์šฉ์„ ๋ฐฐ์›Œ์š”.

๐Ÿง  ๋น„์œ ๋กœ ์ดํ•ด๋˜๋Š” JPA ํ•ต์‹ฌ ๊ฐœ๋…

  • ๋น„์„œ๋กœ ์ดํ•ดํ•˜๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ - ์กฐํšŒ๋ฅผ ์บ์‹ฑํ•˜๊ณ  ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ  ์ฟผ๋ฆฌ๋ฅผ ๋ชจ์•„์„œ ๋ณด๋‚ด์ฃผ๋Š” ๋น„์„œ

  • ํƒ๋ฐฐ ๋ชจ์•„๋ณด๋‚ด๊ธฐ๋กœ ์ดํ•ดํ•˜๋Š” ์“ฐ๊ธฐ ์ง€์—ฐ โ€” ํ•˜๋‚˜์”ฉ ๋ณด๋‚ด๋ฉด ๋น„ํšจ์œจ, ํŠธ๋Ÿญ ๋ถˆ๋Ÿฌ์„œ ํ•œ ๋ฒˆ์— ๋ฐฐ์†ก

  • ๊ฐ€์งœ ์ง์›(ํ”„๋ก์‹œ)์œผ๋กœ ์ดํ•ดํ•˜๋Š” ์ง€์—ฐ ๋กœ๋”ฉ โ€” ์ง„์งœ ์ผ์ด ์ƒ๊ธฐ๊ธฐ ์ „๊นŒ์ง„ ๋Œ€๊ธฐ๋งŒ ํ•˜๋Š” ๊ฐ€์งœ ๊ฐ์ฒด

  • ๋ ˆ๊ณ  ์กฐ๋ฆฝ์œผ๋กœ ์ดํ•ดํ•˜๋Š” ๋™์  ์ฟผ๋ฆฌ โ€” ์กฐ๊ฑด์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋ผ์›Œ ๋งž์ถ”๋Š” QueryDSL


๐ŸŒฑ Lv.1์„ ๋งˆ์นœ ๋ถ„๋“ค์„ ์œ„ํ•œ ๋‹ค์Œ ๋‹จ๊ณ„

  • Lv.1์—์„œ ๋ฐฐ์šด JdbcTemplate์˜ ํ•œ๊ณ„๋ฅผ ์ง์ ‘ ์ฒด๊ฐํ•˜๋ฉฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • "์ด ๊ธฐ์ˆ ์ด ์™œ ํƒ„์ƒํ–ˆ๋Š”๊ฐ€"๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ๊ฐœ๋… ์„ค๋ช….

  • "๊ณ ํ†ต โ†’ ๊ตฌ์›" ํ•™์Šต๋ฒ•: JDBC 35์ค„์˜ ์ง€์˜ฅ์„ ๊ฒช์–ด์•ผ JPA 3์ค„์˜ ํ˜๋ช…์„ ์••๋‹ˆ๋‹ค.


  • ๋ฉด์ ‘ ๋‹ต๋ณ€๊นŒ์ง€ ์—ฐ๊ฒฐ๋˜๋Š” ์‹ค์ „ํ˜• ์ปค๋ฆฌํ˜๋Ÿผ.


โœจ ์ด ๊ฐ•์˜์˜ ํŠน์ง•

๐Ÿ“Œ "์™œ?"๋ฅผ ๋์—†์ด ์งˆ๋ฌธํ•ฉ๋‹ˆ๋‹ค

์ด ๊ฐ•์˜๋Š” "์ด๋ ‡๊ฒŒ ํ•˜์„ธ์š”"๋กœ ๋๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜ ๊ฐ•์˜: "์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. save() ์“ฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค." (X)

์ด ๊ฐ•์˜: ์ˆœ์ˆ˜ JDBC๋กœ SELECT 35์ค„ ์ง€์˜ฅ์„ ์ง์ ‘ ๊ฒช์€ ํ›„, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ 1์ฐจ ์บ์‹œ๊ฐ€ ์™œ ํ˜๋ช…์ธ์ง€ ๋ผˆ์ €๋ฆฌ๊ฒŒ ์ฒด๊ฐ

๋ชจ๋“  ๊ฐœ๋…์€ "์ด ๊ธฐ์ˆ ์ด ์™œ ํƒ„์ƒํ–ˆ๋Š”๊ฐ€"๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. Why๋ฅผ ์ฒด๋“ํ•˜๋ฉด, How๋Š” ์ €์ ˆ๋กœ ๋”ฐ๋ผ์˜ต๋‹ˆ๋‹ค.


๐Ÿ“Œ "๊ณ ํ†ต โ†’ ๊ตฌ์›" ํ•™์Šต๋ฒ•

๋‹จ์ˆœํžˆ ์ •๋‹ต๋งŒ ์•Œ๋ ค์ฃผ๋Š” ๊ฐ•์˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ผ๋ถ€๋Ÿฌ ๊ณ ํ†ต์„ ๊ฒช๊ฒŒ ํ•œ ํ›„, ํ•ด๊ฒฐ์ฑ…์˜ ์œ„๋Œ€ํ•จ์„ ์ฒด๊ฐํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

1์ฃผ์ฐจ: JDBC 35์ค„ SELECT ์ง€์˜ฅ โ†’ JPA์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ 3์ค„๋กœ ๋๋ƒ„

2์ฃผ์ฐจ: EnumType ๋ˆ„๋ฝ์œผ๋กœ ๋ฐ์ดํ„ฐ ์˜ค์—ผ ์ฐธ์‚ฌ โ†’ EnumType.STRING ๋ฐฉ์–ด๋ฒ• / merge()์˜ null ๋ฎ์–ด์“ฐ๊ธฐ ์ฐธ์‚ฌ โ†’ ๋ณ€๊ฒฝ ๊ฐ์ง€ ๊ธฐ๋ฐ˜ ์•ˆ์ „ํ•œ ์ˆ˜์ •

3์ฃผ์ฐจ: ๊ฐ์ฒด์™€ ํ…Œ์ด๋ธ”์˜ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜ ํ˜ผ๋ž€ โ†’ ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์œผ๋กœ ๊น”๋”ํ•˜๊ฒŒ ํ•ด๊ฒฐ / N+1์œผ๋กœ ์ฟผ๋ฆฌ ํญ๋ฐœ โ†’ Fetch Join ํ•œ ์ค„๋กœ ํ•ด๊ฒฐ

4์ฃผ์ฐจ: ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ์— createdAt ๋ณต๋ถ™ ์ง€์˜ฅ โ†’ BaseEntity ํ•œ ๋ฐฉ ํ•ด๊ฒฐ / ๊ฐ’ ํƒ€์ž… ์ปฌ๋ ‰์…˜ ์ „์ฒด ์‚ญ์ œ ์ฐธ์‚ฌ โ†’ ์—”ํ‹ฐํ‹ฐ ์Šน๊ฒฉ ํŒจํ„ด

5์ฃผ์ฐจ: ๋ฌธ์ž์—ด JPQL ์˜คํƒ€๊ฐ€ ๋Ÿฐํƒ€์ž„ ์žฅ์• ๋กœ โ†’ QueryDSL ์ปดํŒŒ์ผ ํƒ€์ž„ ๊ฒ€์ฆ / if๋ฌธ ๋™์  ์ฟผ๋ฆฌ ์ŠคํŒŒ๊ฒŒํ‹ฐ โ†’ BooleanExpression ๋ ˆ๊ณ  ์กฐ๋ฆฝ

์ด ๊ฒฝํ—˜์ด ๋ฉด์ ‘์—์„œ "์ œ๊ฐ€ ์ง์ ‘ ๊ฒช์–ด๋ดค๋Š”๋ฐ์š”..."๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋‹ต๋ณ€์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

JPA์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ถ€ํ„ฐ QueryDSL๊นŒ์ง€, ๋‚ด๋ถ€ ๋™์ž‘์„ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“Œ ๋ฉด์ ‘๊ด€์˜ ์ถ”๊ฐ€ ์งˆ๋ฌธ์„ ์œ ๋„ํ•˜๋Š” ๋‹ต๋ณ€๋ฒ•

๊ฐœ๋…๋งŒ ๋˜์ ธ๋†“๊ณ  ๋๋‚˜๋Š” ๊ฐ•์˜, ๋ฉด์ ‘์—์„œ ์–ด๋–ป๊ฒŒ ์จ๋จน๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ๋Š” ๊ฐ•์˜โ€ฆ ์ €๋Š” ๊ทธ๋Ÿฐ ๊ฐ•์˜๋ฅผ ์ œ์ผ ์‹ซ์–ดํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ฐ•์˜๋Š” ๊ฐœ๋… โ†’ ์ฒดํ—˜ โ†’ ๋ฉด์ ‘ ๋‹ต๋ณ€๊นŒ์ง€ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
(์•„๋ž˜ ์ด๋ฏธ์ง€๋Š” ๋ฐฑ์—”๋“œ ์ด๋ ฅ์„œ ์ฐจ๋ณ„ํ™” ๊ฐ•์˜์˜ ๋ฉด์ ‘ ์ ์ค‘ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค)

์ด๋Ÿฐ ๋ถ„๋“ค๊ป˜ ์ถ”์ฒœํ•ด์š”

JPA๊ฐ€ ๋ญ”์ง€ ๊ฐ์ด ์•ˆ ์žกํ˜€์š”
โœ” JdbcTemplate์œผ๋กœ CRUD๋Š” ํ–ˆ๋Š”๋ฐ, "์˜์†์„ฑ ์ปจํ…์ŠคํŠธ"๊ฐ€ ๋ญ”์ง€ ๋ชจ๋ฅด๋Š” ๋ถ„
โœ” save() ํ˜ธ์ถœํ•˜๋ฉด ์ €์žฅ๋˜๋Š” ๊ฑด ์•„๋Š”๋ฐ, "๋‚ด๋ถ€์—์„œ ๋ญ๊ฐ€ ์ผ์–ด๋‚˜๋Š”์ง€" ๋ชจ๋ฅด๋Š” ๋ถ„
โœ” JPA๋ฅผ "์™œ" ์จ์•ผ ํ•˜๋Š”์ง€ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ณ  ์‹ถ์€ ๋ถ„

์‹ค๋ฌด์—์„œ JPA ์“ฐ๋Š”๋ฐ, ์žฅ์•  ์›์ธ์„ ๋ชจ๋ฅด๊ฒ ์–ด์š”
โœ” N+1 ๋ฌธ์ œ๊ฐ€ ๋ญ”์ง€๋Š” ๋“ค์—ˆ๋Š”๋ฐ "๋‚ด ์ฝ”๋“œ์—์„œ ํ„ฐ์ง€๋ฉด" ๋ชป ์ฐพ๊ฒ ๋Š” ๋ถ„
โœ” @ManyToOne, @OneToMany ๋ถ™์ด๊ธด ํ•˜๋Š”๋ฐ "์™œ ์ด๋ ‡๊ฒŒ ์งœ์•ผ ํ•˜๋Š”์ง€" ์„ค๋ช… ๋ชป ํ•˜๋Š” ๋ถ„
โœ” "๋ณ€๊ฒฝ ๊ฐ์ง€๊ฐ€ ์•ˆ ๋ผ์š”" ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚˜๋ฉด ๊ตฌ๊ธ€๋ง๋ถ€ํ„ฐ ํ•˜๋Š” ๋ถ„

๋ฉด์ ‘ ์ค€๋น„์™€ ์‹ค์Šต์„ ๋™์‹œ์— ํ•˜๊ณ  ์‹ถ์–ด์š”
โœ” "์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์„ค๋ช…ํ•ด๋ณด์„ธ์š”"์— ๊ฒฝํ—˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ต๋ณ€ํ•˜๊ณ  ์‹ถ์€ ๋ถ„
โœ” ์ด๋ก ์ด ์•„๋‹Œ ์‹ค์ „์œผ๋กœ JPA๋ฅผ ์ตํžˆ๊ณ  ์‹ถ์€ ๋ถ„
โœ” "N+1 ํ•ด๊ฒฐํ•ด๋ณด์…จ๋‚˜์š”?" ์งˆ๋ฌธ์— 3๊ฐ€์ง€ ํ•ด๊ฒฐ๋ฒ•์„ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ณ  ์‹ถ์€ ๋ถ„

๐Ÿ—บ๏ธ ์ด ๊ฐ•์˜๋Š” Lv.2์ž…๋‹ˆ๋‹ค

์ด ๊ฐ•์˜๋Š” ๋กœ๋“œ๋งต์˜ ํ•ต์‹ฌ ๋‹จ๊ณ„์˜ˆ์š”. Lv.1์—์„œ Spring Boot์˜ ๊ธฐ์ดˆ๋ฅผ ๋‹ค์กŒ๋‹ค๋ฉด, ์ด์ œ ์‹ค๋ฌด์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ์ด๋Š” JPA๋ฅผ ์ •๋ณตํ•  ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค.

Lv.0 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ•ต์‹ฌ ๊ฐœ๋… - ์Šคํ”„๋ง ์‹œ์ž‘ ์ „ ๊ธฐ์ดˆ ๋‹ค์ง€๊ธฐ

Lv.1 Spring Boot ์ž…๋ฌธ - ์Šคํ”„๋ง์œผ๋กœ API ๋งŒ๋“ค๊ธฐ, ๋ฉด์ ‘ ๋Œ€๋น„

๐Ÿ‘‰ Lv.2 ํ˜„์—… ๊ฐœ๋ฐœ์ž์˜ JPA ์™„์ „ ์ •๋ณต (์ด ๊ฐ•์˜) - ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ถ€ํ„ฐ QueryDSL๊นŒ์ง€

Lv.3 ๋ฐฐํฌ (AWS, CI/CD) - localhost ๋ง๊ณ  ์ง„์งœ ์„ธ์ƒ์— ๊ณต๊ฐœํ•˜๊ธฐ

Lv.5~6 ์•„ํ‚คํ…์ฒ˜ & ์‹ค์ „ ํ”„๋กœ์ ํŠธ - MSA, DDD, ์ด์ปค๋จธ์Šค ์‹œ์Šคํ…œ ๊ตฌ์ถ•

์ง€๊ธˆ ์ด ๊ฐ•์˜์—์„œ ์‹ค๋ฌด ๋ฌด๊ธฐ๋ฅผ ์žฅ์ฐฉํ•˜๊ณ , ๋‹จ๊ณ„๋ณ„๋กœ ๊ฐ™์ด ๊ฐ€๋ณด์‹œ์ฃ !


์ง€๊ธˆ ์ด ๊ฐ•์˜์—์„œ ์‹œ์ž‘ํ•ด์„œ, ๋‹จ๊ณ„๋ณ„๋กœ ๊ฐ™์ด ๊ฐ€๋ณด์‹œ์ฃ !

์Šคํ”„๋ง ๋ถ€ํŠธ Lv3 ์ธ๋„ค์ผ

๐ŸŽ EVENT ๐ŸŽ

๊ฐ•์˜๋ฅผ ์ˆ˜๊ฐ•ํ•ด์ฃผ์‹œ๋Š” ๋ถ„๋“ค์—๊ฒŒ๋งŒ ์ œ๊ณตํ•˜๋Š” ํŠน๋ณ„ ํ˜œํƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

[Lv.2] JPA ๋ฉด์ ‘ ์งˆ๋ฌธ ๋ฌธ์ œ์ง‘์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค

(ํ•ด๋‹น ๋ฌธ์ œ์ง‘์€ ๋…ธ์…˜์˜ ํ˜•ํƒœ๋กœ ๋งํฌ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค!)

์ˆ˜๊ฐ•ํ‰์„ ์ž‘์„ฑํ•ด์ฃผ์‹œ๋Š” ๋ถ„๋“ค๊ป˜ ํ•ด๋‹น ๊ต์žฌ๋ฅผ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค!

์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ˆ˜๊ฐ•ํ‰ ์ธ์ฆ ํ›„ ๋ฐ›์•„๊ฐ€์„ธ์š”!

(์ธ์ฆํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋งจ ๋งˆ์ง€๋ง‰ ๊ฐ•์˜์— ์ ์–ด๋’€์Šต๋‹ˆ๋‹ค __)


๐ŸŽ EVENT 2 ๐ŸŽ

ํ•ด๋‹น ๋งํฌ๋ฅผ ํ†ตํ•ด ๊ตฌ๊ธ€ ์„ค๋ฌธ์„ ์ œ์ถœํ•ด์ฃผ์‹œ๋ฉด

๐ŸŽŸ 15% ํ• ์ธ ์ฟ ํฐ์„ ์ „๋‹ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค ๐ŸŽŸ

๐ŸŽ EVENT 3 ๐ŸŽ

IntelliJ IDE 3๊ฐœ์›” ๋ฌด๋ฃŒ ์ด์šฉ๊ถŒ ์ œ๊ณต!

์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ๊ฐœ๋ฐœ ๊ณต๋ถ€๋ฅผ ์‘์›ํ•˜๋Š” ๋งˆ์Œ์œผ๋กœ JetBrains์™€์˜ ํ˜‘์—…์„ ํ†ตํ•ด ํŠน๋ณ„ํ•œ ํ˜œํƒ์„ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค.
์•„๋ž˜ ํ”„๋กœ๋ชจ์…˜ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด IntelliJ๋ฅผ 3๊ฐœ์›”๊ฐ„ ๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!


โœ… ํ”„๋กœ๋ชจ์…˜ ์ฝ”๋“œ: HYUNJOONPARKxJB
โœ… ํ˜œํƒ ๋‚ด์šฉ: JetBrains ๋‹จ์ผ IDE(์˜ˆ: IntelliJ, PyCharm, WebStorm ๋“ฑ) 3๊ฐœ์›” ๋ฌด๋ฃŒ ์ด์šฉ๊ถŒ
โœ… ์‚ฌ์šฉ ๊ธฐํ•œ: ~ 2026๋…„ 5์›” 13์ผ๊นŒ์ง€
โœ… ์‚ฌ์šฉ ๋ฐฉ๋ฒ•๐Ÿ˜€

1.JetBrains ๊ณต์‹ ์ฟ ํฐ ๋“ฑ๋ก ํŽ˜์ด์ง€ ์ ‘์†

2.์ฝ”๋“œ ์ž…๋ ฅ ํ›„ ์›ํ•˜๋Š” IDE ์„ ํƒ

3.์ด๋ฉ”์ผ๋กœ ๋ฐœ๊ธ‰๋œ ๋ผ์ด์„ ์Šค ํ™•์ธ


โš  ์ฃผ์˜์‚ฌํ•ญ:
์ด ์ฝ”๋“œ๋Š” JetBrains๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๋Š” ์‹ ๊ทœ ์‚ฌ์šฉ์ž๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
(์ด์ „์— JetBrains ์œ ๋ฃŒ ๋ผ์ด์„ ์Šค๋ฅผ ์‚ฌ์šฉํ•ด๋ณธ ์ด๋ ฅ์ด ์—†๋Š” ๋ถ„๋“ค๋งŒ ๋“ฑ๋ก ๊ฐ€๋Šฅ)
(๊ตฌ๊ธ€ ์ด๋ฉ”์ผ ์ƒˆ๋กœ ํŒŒ์„œ ํ•˜๋ฉด ๋ฌดํ•œ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ์–ด์š”)

์ด ๊ฐ•์˜๋ฅผ ๋งŒ๋“  ์‚ฌ๋žŒ

์ฟ ํŒก, ์•ผ๋†€์ž ์ตœ์ข… ๋ฉด์ ‘๊นŒ์ง€ ๋ณด๊ณ  ์˜จ ๋’ท ์ด์•ผ๊ธฐ ์ฐ ํ‘ผ๋‹ค - 6๋…„์ฐจ ๊ฐœ๋ฐœ์ž 24๊ฐœ ํšŒ์‚ฌ ์ด์ง ์Šคํ† ๋ฆฌ [ep 5]

๋”ฉ์ฝ”๋”ฉ์ฝ”(๋ฉ”์ธ๊ฐ•์‚ฌ)

  • 2021 ~ 2022: S ์ฝ”๋”ฉํด๋Ÿฝ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (data-structure) ํŠœํ„ฐ

  • 2022 ~ : ์ฝ”๋”ฉ ์œ ํŠœ๋ธŒ ๋”ฉ์ฝ”๋”ฉ์ฝ” ์šด์˜ (๊ฐœ๋ฐœ์ž ์ทจ์—… ๊ด€๋ จ๋œ ๋‹ค์–‘ํ•œ ์ปจํ…์ธ  ๋ณด์œ )

  • 2022 ~ 2023 : ๋น„๋ฐ”๋ฆฌํผ๋ธ”๋ฆฌ์นด ์„œ๋ฒ„ ๊ฐœ๋ฐœ์ž


  • ์ ˆ๋Œ€ ํ•™์ƒ์„ ํฌ๊ธฐํ•˜์ง€ ์•Š์Œ ๐Ÿฆˆ

  • ๊ฐœ๋ฐœ์ž ์ทจ์—… ๋ฝ€๊ฐœ๊ธฐ ์ปค๋ฎค๋‹ˆํ‹ฐ ์šด์˜ ๋ฐ ์˜คํ”„๋ผ์ธ ๋ชจ์ž„ ์šด์˜


์ˆ˜๊ฐ• ์ „ ์ฐธ๊ณ  ์‚ฌํ•ญ

๋งŒ์•ฝ!! ์ˆ˜๊ฐ• ์‹ ์ฒญํ•˜๊ธฐ ์ „์— ์กฐ๊ธˆ์ด๋ผ๋„ ๊ณ ๋ฏผ๋œ๋‹ค.

๋‚ด๊ฐ€ ์ง€๊ธˆ ์ด ๊ฐ•์˜๋ฅผ ๋“ฃ๋Š”๊ฒŒ ๋งž์„๊นŒ?? ๊ณ ๋ฏผํ•˜์‹œ๋Š” ๋ถ„๋“ค์€ ์–ธ์ œ๋“  ํŽธํ•˜๊ฒŒ ์˜คํ”ˆ ํ†ก๋ฐฉ์œผ๋กœ ๋ฌธ์˜ํ•ด์ฃผ์„ธ์š”!!

๐Ÿ˜ ์—ด์‹ฌํžˆ ๋‹ต๋ณ€๋“œ๋ ค๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ˜ #Java #Spring #Spring Boot #JPA #spring-jpa

์‹ค์Šต ํ™˜๊ฒฝ

  • intellij๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Community(๋ฌด๋ฃŒ) ๋ฒ„์ „๋„ ์•„๋ฌด ์ƒ๊ด€ ์—†์Šต๋‹ˆ๋‹ค.

  • ์œˆ๋„์šฐ, ๋งฅ ์•„๋ฌด ์ƒ๊ด€ ์—†์Šต๋‹ˆ๋‹ค! ๊ฐ ์šด์˜์ฒด์ œ ๋ณ„ ์„ค์น˜ ๋ฐฉ๋ฒ•๋“ค ๋ชจ๋‘ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.


ํ•™์Šต ์ž๋ฃŒ

  • ๋…ธ์…˜ ๋ฐ PDF๋กœ ์ „๋ถ€ ๊ณต์œ ํ•ด๋“œ๋ฆฝ๋‹ˆ๋‹ค!

  • ํ”„๋กœ์ ํŠธ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•ด๋“œ๋ฆฝ๋‹ˆ๋‹ค!

์„ ์ˆ˜ ์ง€์‹ ๋ฐ ์œ ์˜์‚ฌํ•ญ

  • Spring ์‚ด์ง ๋ฐฐ์›Œ๋ณธ ์‚ฌ๋žŒ

  • MySQL CRUD ๊ฒฝํ—˜์ž


์ด๋Ÿฐ ๋ถ„๋“ค๊ป˜
์ถ”์ฒœ๋“œ๋ ค์š”

ํ•™์Šต ๋Œ€์ƒ์€
๋ˆ„๊ตฌ์ผ๊นŒ์š”?

  • JPA๊ฐ€ ๋ญ”์ง€, ์™œ ์จ์•ผ ํ•˜๋Š”์ง€ ๊ฐ๋ถ€ํ„ฐ ์žก๊ณ  ์‹ถ์€ ๋ถ„

  • ๊ฒฝํ—˜ ๊ธฐ๋ฐ˜ ๋‹ต๋ณ€์œผ๋กœ ๋ฉด์ ‘๊ด€์˜ ์ถ”๊ฐ€ ์งˆ๋ฌธ์„ ์œ ๋„ํ•˜๊ณ  ์‹ถ์€ ๋ถ„

  • @ManyToOne์€ ์•Œ๊ฒ ๋Š”๋ฐ ์–‘๋ฐฉํ–ฅ์ด ์™œ ํ•„์š”ํ•œ์ง€, mappedBy๊ฐ€ ๋ญ”์ง€ ์ •๋ฆฌ๊ฐ€ ์•ˆ ๋˜๋Š” ๋ถ„

  • ์ฟผ๋ฆฌ๊ฐ€ ์–ธ์ œ ๋‚˜๊ฐ€๋Š”์ง€, ๋ณ€๊ฒฝ ๊ฐ์ง€๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€, ์™œ update()๋ฅผ ์•ˆ ์จ๋„ ๋˜๋Š”์ง€ ์›๋ฆฌ๋ฅผ ์•Œ๊ณ  ์‹ถ์€ ๋ถ„

  • ์ฟผ๋ฆฌ ๋กœ๊ทธ๋ฅผ ์ฝ๊ณ  ์ง์ ‘ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์ „ ๋Šฅ๋ ฅ์ด ํ•„์š”ํ•œ ๋ถ„

์„ ์ˆ˜ ์ง€์‹,
ํ•„์š”ํ• ๊นŒ์š”?

  • Java ๊ธฐ์ดˆ ๋ฌธ๋ฒ• (if๋ฌธ, for๋ฌธ, ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค)

  • Spring Boot๋กœ ๊ฐ„๋‹จํ•œ REST API๋ฅผ ๋งŒ๋“ค์–ด๋ณธ ๊ฒฝํ—˜

  • JdbcTemplate์œผ๋กœ DB CRUD๋ฅผ ํ•ด๋ณธ ๊ฒฝํ—˜ (SQL SELECT, INSERT ๋“ฑ ๊ธฐ์ดˆ)

์•ˆ๋…•ํ•˜์„ธ์š”
๋”ฉ์ฝ”๋”ฉ์ฝ”์ž…๋‹ˆ๋‹ค.

15,917

๋ช…

์ˆ˜๊ฐ•์ƒ

1,603

๊ฐœ

์ˆ˜๊ฐ•ํ‰

306

๊ฐœ

๋‹ต๋ณ€

4.9

์ 

๊ฐ•์˜ ํ‰์ 

19

๊ฐœ

๊ฐ•์˜

๐Ÿš€ ํ† ์Šค, ํฌํ•ญ๊ณต๋Œ€ ์ถœ์‹  | ํ˜„์—… ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž(+8๋…„)
๐ŸŽฅ2๋งŒ ์œ ํŠœ๋ฒ„ | ๊ฐœ๋ฐœ ์ฝ˜ํ…์ธ  ์ œ์ž‘
๐Ÿ“š ์ธํ”„๋Ÿฐ ๊ฐ•์‚ฌ | ๋ˆ„์  ์ˆ˜๊ฐ•์ƒ 15,000+
๐Ÿ‘ฅ ๊ฐœ๋ฐœ์ž ์ทจ์—… ์ปค๋ฎค๋‹ˆํ‹ฐ ์šด์˜ ์ค‘ (8,000+)
๐Ÿงฉ ์˜คํ”ˆ์†Œ์Šค (Gradle, Spring AI ๋“ฑ) ๋‹ค์ˆ˜ Contributor
๐Ÿ“38๊ฐœ ์„œ๋ฅ˜ ํ•ฉ๊ฒฉ ๋ฐ ํฌ๋ชฝ ์ด๋ ฅ์„œ ์ฒจ์‚ญ 100+ํšŒ ์ด์ƒ ๊ฒฝํ—˜ (ํ‰์  5.0์ )

ํ˜„์—…์—์„œ ์ „๋‹ฌ๋˜๋Š” ์ƒ์ƒํ•œ ์ •๋ณด๋“ค์„ ์‰ฝ๊ณ , ์—ฐ์—ญ์ ์œผ๋กœ ์ดํ•ด๋˜๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

์ธํ”„๋Ÿฐ ์ธํ„ฐ๋ทฐ ๋งํฌ!

๋”๋ณด๊ธฐ

์ปค๋ฆฌํ˜๋Ÿผ

์ „์ฒด

40๊ฐœ โˆ™ (2์‹œ๊ฐ„ 21๋ถ„)

๊ฐ•์˜ ๊ฒŒ์‹œ์ผ: 
๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ์ผ: 

์ˆ˜๊ฐ•ํ‰

์•„์ง ์ถฉ๋ถ„ํ•œ ํ‰๊ฐ€๋ฅผ ๋ฐ›์ง€ ๋ชปํ•œ ๊ฐ•์˜์ž…๋‹ˆ๋‹ค.
๋ชจ๋‘์—๊ฒŒ ๋„์›€์ด ๋˜๋Š” ์ˆ˜๊ฐ•ํ‰์˜ ์ฃผ์ธ๊ณต์ด ๋˜์–ด์ฃผ์„ธ์š”!

๋”ฉ์ฝ”๋”ฉ์ฝ”๋‹˜์˜ ๋‹ค๋ฅธ ๊ฐ•์˜

์ง€์‹๊ณต์œ ์ž๋‹˜์˜ ๋‹ค๋ฅธ ๊ฐ•์˜๋ฅผ ๋งŒ๋‚˜๋ณด์„ธ์š”!

๋น„์Šทํ•œ ๊ฐ•์˜

๊ฐ™์€ ๋ถ„์•ผ์˜ ๋‹ค๋ฅธ ๊ฐ•์˜๋ฅผ ๋งŒ๋‚˜๋ณด์„ธ์š”!

์–ผ๋ฆฌ๋ฒ„๋“œ ํ• ์ธ ์ค‘

โ‚ฉ69,300

30%

โ‚ฉ99,000