๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Project ESG+AI/Tech Basics

27์ผ์ฐจ. IT ๊ฐœ๋… ์ •๋ฆฌ

by GreenJin_S2 2025. 11. 14.

 

 


ํŒŒ์ดํ”„๋ผ์ธ ์—ฐ๊ฒฐ์ด๋ž€?

ํŒŒ์ดํ”„๋ผ์ธ ์—ฐ๊ฒฐ์€ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„์˜ ์ž‘์—…์„ ์ˆœ์„œ๋Œ€๋กœ ์ž๋™์œผ๋กœ ์ด์–ด ๋†“๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.
์‰ฝ๊ฒŒ ๋งํ•ด, ์ผ์ด ํ๋ฅด๋Š” ๊ธธ(ํŒŒ์ดํ”„๋ผ์ธ)์„ ๋งŒ๋“ค๊ณ , ๊ทธ ๊ธธ์„ ์„œ๋กœ ์—ฐ๊ฒฐํ•ด ์ž‘์—…์ด ๋Š๊ธฐ์ง€ ์•Š๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

๋ฐ์ดํ„ฐ๋‚˜ ์—…๋ฌด ์ฒ˜๋ฆฌ์—์„œ๋„ ์ด์™€ ๋น„์Šทํ•˜๊ฒŒ,
A ์ž‘์—…์˜ ๊ฒฐ๊ณผ๊ฐ€ ์ž๋™์œผ๋กœ B ์ž‘์—…์œผ๋กœ ๋„˜์–ด๊ฐ€๋„๋ก ๊ธธ์„ ๋งŒ๋“ค์–ด ๋†“๋Š” ๊ฒƒ์„ ํŒŒ์ดํ”„๋ผ์ธ ์—ฐ๊ฒฐ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

์™œ ์ค‘์š”ํ•œ๊ฐ€?

  • ์‹œ๊ฐ„ ์ ˆ์•ฝ: ๋ฐ˜๋ณต ์ž‘์—…์„ ์ž๋™์œผ๋กœ ์ด์–ด์คŒ
  • ์‹ค์ˆ˜ ๊ฐ์†Œ: ์‚ฌ๋žŒ์ด ์ˆ˜๋™์œผ๋กœ ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜ ์˜ˆ๋ฐฉ
  • ํšจ์œจ ์ฆ๊ฐ€: ์—…๋ฌด ์†๋„ ๋นจ๋ผ์ง
  • ๊ทœ๋ชจ ํ™•์žฅ ๊ฐ€๋Šฅ: ์ž‘์—…๋Ÿ‰์ด ๋Š˜์–ด๋‚˜๋„ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ

์š”์•ฝ

  • ํŒŒ์ดํ”„๋ผ์ธ ์—ฐ๊ฒฐ = ์ž‘์—… ๋‹จ๊ณ„๋ฅผ ์ž๋™์œผ๋กœ ์ด์–ด๋†“๋Š” ๊ฒƒ
  • ๋™์ž‘ ํ๋ฆ„์„ ๋งŒ๋“ค๊ณ  ์ž๋™์œผ๋กœ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜๊ธฐ๋Š” ์‹œ์Šคํ…œ
  • ๋ฐ์ดํ„ฐ, ๊ฐœ๋ฐœ, ์—…๋ฌด ์ž๋™ํ™” ๋“ฑ ๋‹ค์–‘ํ•œ ๋ถ„์•ผ์—์„œ ์‚ฌ์šฉ๋จ

โœ”๏ธ ์Šคํ”„๋ง์—์„œ ์ปดํฌ๋„ŒํŠธ ์Šค์บ”(Component Scan) ์ด๋ž€?

์Šคํ”„๋ง์—์„œ ์ปดํฌ๋„ŒํŠธ ์Šค์บ”(Component Scan) ์ด๋ž€,
์Šคํ”„๋ง์ด ์ž๋™์œผ๋กœ ๊ฐ์ฒด(Bean)๋ฅผ ์ฐพ์•„์„œ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๋งํ•ด.

์•„์ฃผ ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด:

“๋„ˆ๊ฐ€ @Component, @Service, @Repository, @Controller ์ด๋Ÿฐ ๊ฑธ ๋ถ™์—ฌ๋†“๊ธฐ๋งŒ ํ•˜๋ฉด
์Šคํ”„๋ง์ด ์ž๋™์œผ๋กœ ์ฐพ์•„์„œ Bean์œผ๋กœ ๋“ฑ๋กํ•ด์ค„๊ฒŒ!”

๋ผ๋Š” ๊ธฐ๋Šฅ์ด์•ผ.


๐Ÿ” 1. ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์ด ์™œ ํ•„์š”ํ•ด?

์›๋ž˜ ์Šคํ”„๋ง์—์„œ๋Š” Bean์„ ์ด๋ ‡๊ฒŒ ํ•˜๋‚˜ํ•˜๋‚˜ ๋“ฑ๋กํ–ˆ์–ด:

 
@Bean public UserService userService() { return new UserService(); }

๊ทผ๋ฐ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ปค์ง€๋ฉด Bean์ด ์ˆ˜๋ฐฑ ๊ฐœ๊ฐ€ ๋˜๊ณ  ํ•œ๋•€ํ•œ๋•€ ๋“ฑ๋กํ•˜๋Š” ๊ฒŒ ํž˜๋“ค๊ฒ ์ง€?

๊ทธ๋ž˜์„œ ๋“ฑ์žฅํ•œ ๊ฒƒ์ด ์ปดํฌ๋„ŒํŠธ ์Šค์บ”!

์Šคํ”„๋ง์ด ์ง€์ •๋œ ํŒจํ‚ค์ง€๋ฅผ ์ญ‰ ์Šค์บ”ํ•˜๋ฉด์„œ
@Component ๊ณ„์—ด ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์ž๋™ ๋“ฑ๋กํ•ด์ค˜.


๐Ÿ” 2. ์–ด๋–ค ๊ฒƒ๋“ค์ด ์Šค์บ” ๋Œ€์ƒ์ธ๊ฐ€?

์•„๋ž˜ ์–ด๋…ธํ…Œ์ด์…˜์€ ์ „๋ถ€ “์Šค์บ” ๋Œ€์ƒ”์ด์•ผ, ์ฆ‰ Bean์œผ๋กœ ์ž๋™ ๋“ฑ๋ก๋จ:

์–ด๋…ธํ…Œ์ด์…˜์—ญํ• 
@Component ๊ธฐ๋ณธ ์ปดํฌ๋„ŒํŠธ
@Service ์„œ๋น„์Šค ๊ณ„์ธต
@Repository DB/DAO ๊ณ„์ธต
@Controller MVC ์ปจํŠธ๋กค๋Ÿฌ
@RestController REST API ์ปจํŠธ๋กค๋Ÿฌ

์ด ๋ชจ๋“  ๊ฒƒ๋“ค์ด ์‚ฌ์‹ค ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ „๋ถ€ @Component ๊ธฐ๋ฐ˜์ด์•ผ.


๐Ÿ” 3. ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์˜ ๋™์ž‘ ํ๋ฆ„

  1. ์Šคํ”„๋ง ๋ถ€ํŠธ ์‹œ์ž‘
  2. @SpringBootApplication ์•ˆ์˜
    @ComponentScan์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ํ˜„์žฌ ํŒจํ‚ค์ง€ ๊ธฐ์ค€์œผ๋กœ ํ•˜์œ„ ํŒจํ‚ค์ง€๋ฅผ ์ „๋ถ€ ๊ฒ€์ƒ‰
  3. @Component ๊ณ„์—ด์ด ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ๋ฐœ๊ฒฌ
  4. ์ž๋™์œผ๋กœ Bean ๋“ฑ๋ก
  5. DI(์˜์กด ์ฃผ์ž…)๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ ๊ณณ์— ์‚ฝ์ž…๋จ (@Autowired, ์ƒ์„ฑ์ž ์ฃผ์ž… ๋“ฑ)

๐Ÿ” 4. ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํฌ์ธํŠธ

๐ŸŽฏ "๊ฐ™์€ ํŒจํ‚ค์ง€ ๋˜๋Š” ํ•˜์œ„ ํŒจํ‚ค์ง€"๋งŒ ์Šค์บ”ํ•œ๋‹ค

์Šคํ”„๋ง ๋ถ€ํŠธ์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ๊ฐ€ ์ด๋Ÿฐ ์ด์œ ์•ผ:

 

์ด๋ ‡๊ฒŒ๋งŒ ํ•ด๋†”๋„,

  • Bean ๋“ฑ๋ก ์ฝ”๋“œ ์—†์Œ
  • ์„ค์ • ์—†์Œ

๊ทธ๋ƒฅ ์Šคํ”„๋ง์ด ์ž๋™์œผ๋กœ ๊ฐ์ง€ํ•ด์„œ
memberService๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ Bean์„ ๋งŒ๋“ค์–ด์ค€๋‹ค.

 

 


์œ„์˜ ๊ฒƒ์€ ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์— ๋“ฑ๋ก๋˜๋Š” ๊ฒƒ์ด ๋งž๋Š”๊ฐ€?

 

๋„ค, ๋งž์•„!
์ปดํฌ๋„ŒํŠธ ์Šค์บ”์œผ๋กœ ์ฐพ์€ ํด๋ž˜์Šค๋“ค์€ ์ „๋ถ€ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ(= ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ)์— Bean์œผ๋กœ ๋“ฑ๋ก๋ผ.

์ •ํ™•ํžˆ๋Š” ์ด๋ ‡๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์–ด:

“์ปดํฌ๋„ŒํŠธ ์Šค์บ”์€ Bean์„ Spring ApplicationContext ์— ์ž๋™ ๋“ฑ๋กํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.”


๐Ÿ” ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์— ๋“ฑ๋ก๋œ๋‹ค๋Š” ์˜๋ฏธ

์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ(ApplicationContext)๋Š” ์ผ์ข…์˜ “Bean ์ €์žฅ์†Œ”์•ผ.

  1. ์Šคํ”„๋ง์ด ์•ฑ์„ ์‹œ์ž‘ํ•˜๋ฉด ApplicationContext๊ฐ€ ์ƒ์„ฑ๋จ
  2. ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์ด ์‹œ์ž‘๋จ
  3. @Component, @Service, @Repository, @Controller๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ๋ฐœ๊ฒฌ
  4. ์ด ํด๋ž˜์Šค๋“ค๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ApplicationContext์— ์ €์žฅ
  5. ํ•„์š”ํ•  ๋•Œ DI(@Autowired, ์ƒ์„ฑ์ž ์ฃผ์ž… ๋“ฑ)๋กœ ๊บผ๋‚ด์„œ ์‚ฌ์šฉ

์ฆ‰, “์Šคํ”„๋ง์ด ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด”๊ฐ€ ๋œ๋‹ค๋Š” ๋œป์ด์•ผ.


๐Ÿ” ์ •๋ฆฌ ๊ทธ๋ฆผ

 
@Component @Service @Controller @Repository ↓ ์ปดํฌ๋„ŒํŠธ ์Šค์บ” ↓ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ (ApplicationContext)์— Bean ๋“ฑ๋ก ↓ DI๋กœ ์ฃผ์ž… ๊ฐ€๋Šฅ

๐Ÿ” ํ•ต์‹ฌ ์š”์•ฝ

  • ์ปดํฌ๋„ŒํŠธ ์Šค์บ” = Bean ์ž๋™ ๋“ฑ๋ก ๊ธฐ๋Šฅ
  • ์ž๋™ ๋“ฑ๋ก๋œ Bean = ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ๊ฐ€ ๊ด€๋ฆฌ
  • ์ปจํ…์ŠคํŠธ ๋“ฑ๋ก → DI๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง€๊ณ , ์‹ฑ๊ธ€ํ†ค ๊ด€๋ฆฌ๋„ ์Šคํ”„๋ง์ด ํ•ด์คŒ

JPA์—์„œ ํผ์‹œ์Šคํ„ด์Šค ์ปจํ…์ŠคํŠธ๋Š” ์Šคํ”„๋ง์—์„œ ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์™€ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ๊ฐ€?

 

 

์ด ๋‘ ๊ฐœ๋Š” ์ด๋ฆ„์ด ๋น„์Šทํ•ด์„œ ์ดˆ๋ณด์ž๊ฐ€ ๊ฐ€์žฅ ๋งŽ์ด ํ—ท๊ฐˆ๋ ค ํ•˜๋Š” ๋ถ€๋ถ„์ด์•ผ.
ํ•˜์ง€๋งŒ ์„ฑ๊ฒฉ·์—ญํ• ·์ €์žฅํ•˜๋Š” ๋Œ€์ƒ์ด ์™„์ „ํžˆ ๋‹ฌ๋ผ.

์•„์ฃผ ์‰ฝ๊ฒŒ, ๋น„๊ต ์ค‘์‹ฌ์œผ๋กœ ์„ค๋ช…ํ• ๊ฒŒ.


๐Ÿ”ฅ ํ•œ ์ค„ ํ•ต์‹ฌ ์š”์•ฝ

์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ = ์Šคํ”„๋ง์ด ๊ด€๋ฆฌํ•˜๋Š” “Bean ์ €์žฅ์†Œ”
ํผ์‹œ์Šคํ„ด์Šค ์ปจํ…์ŠคํŠธ = JPA๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” “์—”ํ‹ฐํ‹ฐ ์ €์žฅ์†Œ(์˜์†์„ฑ ๊ด€๋ฆฌ ์ฐฝ๊ณ )”

๋‘˜ ๋‹ค “์ปจํ…์ŠคํŠธ”์ง€๋งŒ ์ „ํ˜€ ๋‹ค๋ฅธ ์„ธ๊ณ„์•ผ.


๐Ÿ“Œ 1. ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ(Spring ApplicationContext)

โœ”๏ธ ๋ˆ„๊ฐ€ ๊ด€๋ฆฌ?

โžก๏ธ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ

โœ”๏ธ ๋ฌด์—‡์„ ์ €์žฅ?

โžก๏ธ ์Šคํ”„๋ง Bean (Service, Repository, Controller ๋“ฑ)

โœ”๏ธ ๋ชฉ์ 

โžก๏ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปดํฌ๋„ŒํŠธ(Bean)๋ฅผ ์ƒ์„ฑ·์ดˆ๊ธฐํ™”·์†Œ๋ฉธ๊นŒ์ง€ ๊ด€๋ฆฌํ•˜๋Š” IoC ์ปจํ…Œ์ด๋„ˆ

โœ”๏ธ ์˜ˆ์‹œ

  • MemberService
  • MemberRepository
  • OrderService
  • PasswordEncoder
  •  

์ด๋Ÿฐ ๊ฒƒ๋“ค์ด ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์— ๋“ค์–ด ์žˆ์Œ.

โœ”๏ธ ์ƒ์„ฑ ์‹œ์ 

โžก๏ธ ์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘๋  ๋•Œ


๐Ÿ“Œ 2. ํผ์‹œ์Šคํ„ด์Šค ์ปจํ…์ŠคํŠธ(Persistence Context, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ)

โœ”๏ธ ๋ˆ„๊ฐ€ ๊ด€๋ฆฌ?

โžก๏ธ JPA + Hibernate

โœ”๏ธ ๋ฌด์—‡์„ ์ €์žฅ?

โžก๏ธ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด(Entity)
(DB ํ…Œ์ด๋ธ” row๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ ๊ฒƒ๋“ค)

โœ”๏ธ ๋ชฉ์ 

โžก๏ธ ์—”ํ‹ฐํ‹ฐ์˜ ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ
โžก๏ธ 1์ฐจ ์บ์‹œ ์œ ์ง€
โžก๏ธ ๋ณ€๊ฒฝ ๊ฐ์ง€(Dirty Checking)
โžก๏ธ ์ง€์—ฐ ๋กœ๋”ฉ(Lazy Loading)
โžก๏ธ DB UPDATE ์ž๋™ ๋ฐ˜์˜

โœ”๏ธ ์˜ˆ์‹œ๋กœ ์ €์žฅ๋˜๋Š” ๊ฒƒ

  • Member ์—”ํ‹ฐํ‹ฐ
  • Order ์—”ํ‹ฐํ‹ฐ
  • Product ์—”ํ‹ฐํ‹ฐ
    (์‹ค์ œ๋กœ DB์— ์ €์žฅ๋˜๊ธฐ ์ „ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋“ค์ด ์—ฌ๊ธฐ์— ๋จธ๋ฌด๋ฆ„)

โœ”๏ธ ์ƒ์„ฑ ์‹œ์ 

โžก๏ธ ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋  ๋•Œ(EntityManager ์—ด๋ฆด ๋•Œ)


๐Ÿ”ฅ ์™„์ „ ๋‹ค๋ฅธ ์˜ˆ์‹œ๋กœ ๋น„์œ ํ•˜๋ฉด?

โœ”๏ธ ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ = “์‚ฌ๋žŒ(์„œ๋น„์Šค, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ)๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํšŒ์‚ฌ ์กฐ์ง๋„”

  • ํšŒ์‚ฌ๋Š” ์ง์›(Bean)์„ ๊ด€๋ฆฌ
  • ์–ธ์ œ ์ƒ์„ฑ๋˜๊ณ , ์–ธ์ œ ์“ฐ์ด๊ณ , ์–ธ์ œ ์—†์–ด์ง€๋Š”์ง€ ๊ด€๋ฆฌ

โœ”๏ธ ํผ์‹œ์Šคํ„ด์Šค ์ปจํ…์ŠคํŠธ = “์ฐฝ๊ณ ์—์„œ ๋ฌผ๊ฑด(์—”ํ‹ฐํ‹ฐ)์„ ๋ณด๊ด€·์ˆ˜์ •·์ถ”์ ํ•˜๋Š” ์žฌ๊ณ  ์‹œ์Šคํ…œ”

  • ์ฐฝ๊ณ ์—๋Š” ์ œํ’ˆ(์—”ํ‹ฐํ‹ฐ)์ด ๋‹ด๊น€
  • ์ œํ’ˆ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์ž๋™์œผ๋กœ DB์— ๋ฐ˜์˜๋จ(Dirty Checking)
  • ์ด๋ฏธ ์ €์žฅ๋œ ์ œํ’ˆ์€ ๋‹ค์‹œ ์กฐํšŒํ•˜์ง€ ์•Š๊ณ  ์บ์‹œ์—์„œ ๋ฐ”๋กœ ์คŒ(1์ฐจ ์บ์‹œ)

์ „ํ˜€ ๋‹ค๋ฅธ ์กด์žฌ์•ผ!


๐Ÿ“Œ 3. ๋‘ ์ปจํ…์ŠคํŠธ์˜ ์ฐจ์ด ํ•œ๋ˆˆ ๋น„๊ตํ‘œ

๊ตฌ๋ถ„์Šคํ”„๋ง ์ปจํ…์ŠคํŠธํผ์‹œ์Šคํ„ด์Šค ์ปจํ…์ŠคํŠธ
๊ด€๋ฆฌ ์ฃผ์ฒด Spring Framework JPA/Hibernate
์ €์žฅ ๋Œ€์ƒ Bean(์„œ๋น„์Šค, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ) ์—”ํ‹ฐํ‹ฐ(Entity)
์ƒ์„ฑ ์‹œ์  ์„œ๋ฒ„ ์‹œ์ž‘ ์‹œ ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์‹œ
์—ญํ•  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ์ฒด ๊ด€๋ฆฌ ์—”ํ‹ฐํ‹ฐ ์˜์†/๋ณ€๊ฒฝ๊ฐ์ง€/์บ์‹ฑ
๋ผ์ดํ”„์‚ฌ์ดํด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด ํŠธ๋žœ์žญ์…˜ ๋‹จ์œ„

๐Ÿ“Œ 4. ํ—ท๊ฐˆ๋ฆฌ๋Š” ํ•ต์‹ฌ ํฌ์ธํŠธ

โŒ ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์—๋Š” ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค
โŒ ํผ์‹œ์Šคํ„ด์Šค ์ปจํ…์ŠคํŠธ์—๋Š” Bean์ด ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค
โญ• ๋‘˜์€ ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋‹ค
โญ• Repository Bean์€ ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์— ์žˆ์ง€๋งŒ
Repository๊ฐ€ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ๊ทธ ์—”ํ‹ฐํ‹ฐ๋Š” ํผ์‹œ์Šคํ„ด์Šค ์ปจํ…์ŠคํŠธ์— ๋“ค์–ด๊ฐ


๐Ÿ”ฅ ๋งˆ์ง€๋ง‰ ์š”์•ฝ

์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ = ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ Bean ์ €์žฅ์†Œ
ํผ์‹œ์Šคํ„ด์Šค ์ปจํ…์ŠคํŠธ = JPA์˜ ์—”ํ‹ฐํ‹ฐ ์ €์žฅ์†Œ(์˜์†์„ฑ ๊ด€๋ฆฌ)
๋‘˜์€ ๋ชฉ์ ·์—ญํ• ·์ €์žฅ ๋Œ€์ƒ ๋ชจ๋‘ ๋‹ค๋ฅด๋‹ค.

 

 

 


์ฟผ๋ฆฌ DSL๊ณผ JPA์˜ ํ†ตํ•ฉ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ๊ณ , ๋ช‡๋…„๋„๋ถ€ํ„ฐ ์‚ฌ์šฉ๋œ๊ฑด์ง€ ํ•œ๊ตญ ๊ฐœ๋ฐœ์ž๋“ค์€ ํŠนํžˆ SI์—์„œ๋Š” ์–ด๋–ค์ง€ ์„ค๋ช…ํ•ด์ค˜

ChatGPT์˜ ๋ง:

์•„์ฃผ ํ•ต์‹ฌ์ ์œผ๋กœ **“QueryDSL์ด JPA์™€ ์–ด๋–ป๊ฒŒ ํ†ตํ•ฉ๋˜๋Š”์ง€”, “์–ธ์ œ๋ถ€ํ„ฐ ์“ฐ์˜€๋Š”์ง€”, “ํ•œ๊ตญ SI ๊ฐœ๋ฐœํ™˜๊ฒฝ์—์„œ์˜ ์‹ค์ œ ์‚ฌ์šฉ ๋ฌธํ™””**๊นŒ์ง€ ๋ชจ๋‘ ์ •๋ฆฌํ•ด์ค„๊ฒŒ.


โœ… 1. QueryDSL๊ณผ JPA์˜ ํ†ตํ•ฉ์ด๋ž€?

JPA๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ JPQL์ด๋ผ๋Š” ๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ ์ฟผ๋ฆฌ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•ด.

์˜ˆ:

 
String jpql = "select m from Member m where m.age > :age";

๋ฌธ์ž์—ด์ด๋ผ์„œ

  • ์ปดํŒŒ์ผ ํƒ€์ž„ ์ฒดํฌ ๋ถˆ๊ฐ€
  • ์˜คํƒ€ ๋ฐœ์ƒ ๋นˆ๋ฒˆ
  • ๋ฆฌํŒฉํ„ฐ๋ง์ด ์–ด๋ ค์›€
  • ๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ์ด ๋ณต์žกํ•จ
    ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์–ด.

๊ทธ๋ž˜์„œ ๋‚˜์˜จ ๊ฒŒ QueryDSL.


๐Ÿ“Œ QueryDSL์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

โœ”๏ธ 1) ํƒ€์ž… ์•ˆ์ „ํ•œ ์ฟผ๋ฆฌ

์ปดํŒŒ์ผ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ์žก์Œ.

โœ”๏ธ 2) ์—”ํ‹ฐํ‹ฐ ๊ธฐ๋ฐ˜ ์ž๋™ Qํด๋ž˜์Šค ์ƒ์„ฑ

์˜ˆ:

 
QMember member = QMember.member;

โœ”๏ธ 3) ๋™์  ์ฟผ๋ฆฌ๊ฐ€ ๋งค์šฐ ์‰ฌ์›€

BooleanBuilder, Predicate ์กฐํ•ฉ ๋“ฑ.

โœ”๏ธ 4) JPAQueryFactory๋ฅผ ํ†ตํ•œ ์œ ์—ฐํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ

์˜ˆ๋ฅผ ๋“ค์–ด:

 
QMember m = QMember.member; List<Member> result = queryFactory .selectFrom(m) .where(m.age.gt(20)) .fetch();

์ด๊ฒŒ ๋ฐ”๋กœ QueryDSL + JPA ํ†ตํ•ฉ์˜ ์™„์„ฑ๋œ ํ˜•ํƒœ์•ผ.


๐Ÿ“Œ 2. JPA์™€ QueryDSL์˜ ํ†ตํ•ฉ ๋ฐฉ์‹

JPAQueryFactory๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋ฉด ๋จ.

โฌ‡ ๊ตฌ์กฐ ํ๋ฆ„

 
JPA EntityManager ↓ JPAQueryFactory(QueryDSL) ↓ QClass ์ƒ์„ฑ๊ธฐ (annotation processing) ↓ ํƒ€์ž… ์•ˆ์ „ ์ฟผ๋ฆฌ ์ƒ์„ฑ ↓ JPQL๋กœ ๋ณ€ํ™˜ → Hibernate ์‹คํ–‰

์ฆ‰,

QueryDSL์€ JPA ์œ„์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, ๊ฒฐ๊ตญ ๋‚ด๋ถ€์—์„œ๋Š” JPQL → SQL ๋กœ ๋ณ€ํ™˜๋œ๋‹ค.


๐Ÿ“Œ 3. QueryDSL์€ ์–ธ์ œ๋ถ€ํ„ฐ ์‚ฌ์šฉ๋˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‚˜?

์ •ํ™•ํ•œ ์—ญ์‚ฌ:

  • ์ดˆ๊ธฐ ๊ฐœ๋ฐœ ์‹œ์ : ์•ฝ 2009~2010๋…„
    ๋‹น์‹œ Spring + Hibernate ํ™˜๊ฒฝ์—์„œ ํƒ€์ž… ์„ธ์ดํ”„ ์ฟผ๋ฆฌ ์–ธ์–ด๊ฐ€ ํ•„์š”ํ•ด ๋“ฑ์žฅ.
  • ๋ณธ๊ฒฉ์ ์œผ๋กœ JPA์™€ ํ•จ๊ป˜ ๊ตญ๋‚ด์—์„œ ํ™•์‚ฐ๋œ ์‹œ๊ธฐ: 2014~2016๋…„
  • ์Šคํ”„๋ง๋ถ€ํŠธ ๋„์ž… ์ดํ›„ ์ „๊ตญ์ ์œผ๋กœ ํผ์ง„ ์‹œ๊ธฐ: 2018~2022๋…„
    (์Šคํ”„๋ง๋ถ€ํŠธ + JPA ํ‘œ์ค€ํ™” → QueryDSL ์ฑ„ํƒ ์ฆ๊ฐ€)

โ€ป ํŠนํžˆ "์Šคํ”„๋ง๋ถ€ํŠธ 2.x + JPA" ์กฐํ•ฉ์ด ๋œจ๋ฉด์„œ QueryDSL์ด ๋ฐ˜ ํ•„์ˆ˜๋กœ ์ž๋ฆฌ ์žก์Œ.


๐Ÿ“Œ 4. ํ•œ๊ตญ ๊ฐœ๋ฐœ์ž๋“ค, ํŠนํžˆ SI ํ˜„์žฅ์—์„œ๋Š” ์–ด๋–ค๊ฐ€?

ํ•œ๊ตญ SI ์‹ค๋ฌด์˜ ๋ถ„์œ„๊ธฐ๋ฅผ ์ •ํ™•ํžˆ ๋งํ•ด์ค„๊ฒŒ.


๐Ÿ‡ฐ๐Ÿ‡ท ํ•œ๊ตญ SI์—์„œ QueryDSL ์‚ฌ์šฉ ๋ฌธํ™”

โœ”๏ธ โ‘  2015~2020๋…„: QueryDSL ์ „์„ฑ๊ธฐ

  • ๊ตญ๋‚ด SI/๋Œ€๊ธฐ์—…์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ๋˜ JPA ์ฟผ๋ฆฌ ๊ธฐ์ˆ 
  • ๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ JPQL๋ณด๋‹ค ์•ˆ์ •์ 
  • ๋™์  ์ฟผ๋ฆฌ๊ฐ€ ์‰ฌ์›Œ์„œ ๋ณต์žกํ•œ ์—…๋ฌด ์‹œ์Šคํ…œ์— ์ ํ•ฉ
  • ๋งŽ์€ ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ์ด QueryDSL ๊ธฐ๋ฐ˜์œผ๋กœ ํ˜„์žฌ๊นŒ์ง€ ์œ ์ง€

โœ”๏ธ โ‘ก 2021๋…„ ์ดํ›„ ๋ณ€ํ™”: “JPA vs MyBatis ์žฌ๋Œ€๊ฒฐ”

ํ•œ๊ตญ SI๋Š” ์›๋ž˜ MyBatis๊ฐ€ ๊ฐ•์„ธ.
ํŠนํžˆ SI๋Š” ๋‹ค์Œ ์ด์œ ๋กœ MyBatis๋ฅผ ์„ ํ˜ธํ•จ:

  • ์ฟผ๋ฆฌ๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ œ์–ด ๊ฐ€๋Šฅ
  • ๋ณต์žกํ•œ SQL ์ž‘์„ฑ ํŽธํ•จ
  • DBA์™€ ํ˜‘์—…ํ•˜๊ธฐ ์œ ๋ฆฌ
  • ๋ ˆ๊ฑฐ์‹œ๊ฐ€ ์ „๋ถ€ MyBatis ๊ธฐ๋ฐ˜

๊ทธ๋ž˜์„œ SI์—์„œ๋Š” ๋‹ค์Œ ํŒจํ„ด์ด ๋‚˜ํƒ€๋‚จ:

๋ถ„์•ผ์„ ํ˜ธ ๊ธฐ์ˆ 
์Šคํƒ€ํŠธ์—…, ํ”Œ๋žซํผ JPA + QueryDSL
SI, ๋Œ€ํ˜• ๊ณต๊ณต ํ”„๋กœ์ ํŠธ MyBatis ๋˜๋Š” QueryDSL ํ˜ผ์šฉ
๋ฐ์ดํ„ฐ ๋น„์ค‘ ํฐ ํ”„๋กœ์ ํŠธ MyBatis

โœ”๏ธ โ‘ข 2023~2025๋…„: QueryDSL ์œ ์ง€ or JPA + Spring Data ์ž์ฒด Query ์ด์šฉ

์ตœ๊ทผ ๋ณ€๋™:

  • ๊ณต์‹์ ์œผ๋กœ QueryDSL์€ ๋Œ€๊ทœ๋ชจ ์œ ์ง€๋ณด์ˆ˜ ํŒ€์ด ์—†์–ด์„œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋А๋ฆผ
  • ๊ทธ๋ž˜์„œ ์™„์ „ ์‚ฌ๋ผ์ง€์ง€ ์•Š๊ณ  "์•„์ง๋„ ๋งŽ์ด ์“ฐ์ด๋Š” ์‹ค๋ฌด ํ‘œ์ค€"์ด์ง€๋งŒ,
    ๋Œ€์ฒด ์†”๋ฃจ์…˜๋„ ๋“ฑ์žฅ:
    • Spring Data JPA์˜ @Query
    • Query By Example (QBE)
    • Spring Data JDBC
    • JOOQ ์‚ฌ์šฉ ์ฆ๊ฐ€(ํŠนํžˆ ๊ธˆ์œต๊ถŒ)

โ€ป ํ•˜์ง€๋งŒ, ์—ฌ์ „ํžˆ ์‹ค๋ฌด JPA ์‚ฌ์šฉ์ž์˜ 70% ์ด์ƒ์€ QueryDSL ์‚ฌ์šฉ ๊ฒฝํ—˜ ์žˆ์Œ.


๐Ÿ“Œ 5. ๊ฒฐ๋ก 

โœ”๏ธ QueryDSL + JPA ํ†ตํ•ฉ์˜ ์˜๋ฏธ

  • JPA ๊ธฐ์ค€์˜ ์ฟผ๋ฆฌ๋ฅผ ํƒ€์ž… ์•ˆ์ „ํ•˜๊ณ  ๋™์ ์œผ๋กœ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ž‘์„ฑ ๊ฐ€๋Šฅ
  • JPQL์˜ ๋ฌธ์ž์—ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ JPA ์ตœ๊ณ ์˜ ๋™๋ฐ˜์ž

โœ”๏ธ ์–ธ์ œ๋ถ€ํ„ฐ?

  • 2010๋…„๊ฒฝ ์ฒซ ๋“ฑ์žฅ
  • 2014~2020๋…„ ๊ตญ๋‚ด JPA ์‹œ์žฅ์—์„œ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€
  • ์ง€๊ธˆ๋„ ์—ฌ์ „ํžˆ ๋งค์šฐ ๋„๋ฆฌ ์‚ฌ์šฉ๋จ

โœ”๏ธ ํ•œ๊ตญ SI์—์„œ๋Š”?

  • ์—ฌ์ „ํžˆ QueryDSL ์‚ฌ์šฉ ๋งŽ์Œ
  • ํ•˜์ง€๋งŒ MyBatis๋„ ์—ฌ์ „ํžˆ ๊ฐ•๋ ฅ
  • ์ตœ์‹  ํ”„๋กœ์ ํŠธ๋Š” JPA + QueryDSL ํ˜ผํ•ฉ์ด ๋งŽ์Œ