๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Spring/์Šคํ”„๋ง DB

1. JDBC ์ดํ•ด

๐Ÿ’ก ๋ณธ ๊ฒŒ์‹œ๊ธ€์€ ๊น€์˜ํ•œ๋‹˜์˜ ์ธํ”„๋Ÿฐ(Inflearn) ๊ฐ•์˜ ์Šคํ”„๋ง DB 1ํŽธ - ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ํ•ต์‹ฌ ์›๋ฆฌ ์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๊ณ , ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

1. JDBC ์ดํ•ด

1๏ธโƒฃ JDBC ๋“ฑ์žฅ ์ด์œ 

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์˜ ๋ฐ์ดํ„ฐ ํ™œ์šฉ
    • ๋Œ€๋ถ€๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(DB)์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์กฐํšŒํ•˜๋ฉด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ DB์™€ ์—ฐ๊ฒฐ๋˜์–ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์™€ DB์˜ ์—ฐ๊ฒฐ ๋ฐฉ์‹

  1. ์ปค๋„ฅ์…˜ ์—ฐ๊ฒฐ
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋Š” ์ฃผ๋กœ TCP/IP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜์—ฌ DB์™€ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  2. SQL ์ „๋‹ฌ
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋Š” DB๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” SQL์„ ์—ฐ๊ฒฐ๋œ ์ปค๋„ฅ์…˜์„ ํ†ตํ•ด DB๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ฒฐ๊ณผ ์‘๋‹ต
    • DB๋Š” ์ „๋‹ฌ๋œ SQL์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์— ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.
    • ์‘๋‹ต๋ฐ›์€ ๊ฒฐ๊ณผ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์—์„œ ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.

3๏ธโƒฃ ์˜›๋‚  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ์˜ ๋ฌธ์ œ์ 

๋ฌธ์ œ ์›์ธ

  • ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์ข…๋ฅ˜๊ฐ€ ๋งŽ์œผ๋ฉฐ, ๊ฐ๊ฐ์˜ DB๋Š” ์ปค๋„ฅ์…˜ ์—ฐ๊ฒฐ, SQL ์ „๋‹ฌ, ์‘๋‹ต ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ์„œ๋กœ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
  • ์ด๋กœ ์ธํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ์  1: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€๊ฒฝ ์‹œ ์ฝ”๋“œ ์ˆ˜์ • ํ•„์š”

  • ํŠน์ • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(์˜ˆ: MySQL)๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ, ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(์˜ˆ: Oracle)๋กœ ์ „ํ™˜ํ•˜๋ ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์˜ DB ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ์  2: ๊ฐœ๋ฐœ์ž์˜ ์ถ”๊ฐ€ ํ•™์Šต ๋ถ€๋‹ด

  • ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ DB์˜ ์ปค๋„ฅ์…˜ ์—ฐ๊ฒฐ, SQL ์ „๋‹ฌ, ๊ฒฐ๊ณผ ์‘๋‹ต ๋ฐฉ์‹์„ ๊ฐ๊ฐ ํ•™์Šตํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ข…๋ฅ˜๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ํ•™์Šต ๋น„์šฉ์ด ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

4๏ธโƒฃ JDBC์˜ ๋“ฑ์žฅ

JDBC(Java Database Connectivity)๋ž€?

  • JDBC๋Š” ์ž๋ฐ”์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ‘œ์ค€ํ™”๋œ ์ž๋ฐ” API์ž…๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ํ†ต์‹  ๋ฐฉ์‹์— ๋Œ€ํ•œ ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•˜์—ฌ ์œ„์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

JDBC ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค

JDBC๋Š” ๋‹ค์Œ 3๊ฐ€์ง€ ์ฃผ์š” ๊ธฐ๋Šฅ์„ ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

  1. Connection
    • DB์™€์˜ ์—ฐ๊ฒฐ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: java.sql.Connection
  2. Statement
    • SQL ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: java.sql.Statement
  3. ResultSet
    • SQL ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์‘๋‹ต๋ฐ›๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.
    • ์˜ˆ: java.sql.ResultSet

  • ์ž๋ฐ”๋Š” ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๋“ค์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ข…๋ฅ˜์— ์ƒ๊ด€์—†์ด ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ํ‘œ์ค€ํ™”๋œ ๊ฐœ๋ฐœ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์ฝ”๋“œ์˜ ์ด์‹์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋†’์•„์ง‘๋‹ˆ๋‹ค.

5๏ธโƒฃ JDBC ๋“œ๋ผ์ด๋ฒ„

  • JDBC๋Š” ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์ •์˜ํ•˜๋ฉฐ, ์‹ค์ œ ๋™์ž‘์€ DB ๋ฒค๋”(ํšŒ์‚ฌ)๊ฐ€ ์ œ๊ณตํ•˜๋Š” JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.
  • ๊ฐ DB ๋ฒค๋”๋Š” ์ž์‹ ์˜ DB์— ๋งž๋Š” JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” JDBC ๋“œ๋ผ์ด๋ฒ„ ์˜ˆ์‹œ

  1. MySQL JDBC ๋“œ๋ผ์ด๋ฒ„
    • MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋“œ๋ผ์ด๋ฒ„.
    • ์˜ˆ: com.mysql.cj.jdbc.Driver
  2. Oracle JDBC ๋“œ๋ผ์ด๋ฒ„
    • Oracle ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋“œ๋ผ์ด๋ฒ„.
    • ์˜ˆ: oracle.jdbc.OracleDriver
  3. PostgreSQL JDBC ๋“œ๋ผ์ด๋ฒ„
    • PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋“œ๋ผ์ด๋ฒ„.
    • ์˜ˆ: org.postgresql.Driver

JDBC ๋“œ๋ผ์ด๋ฒ„์˜ ์—ญํ• 

  • JDBC ๋“œ๋ผ์ด๋ฒ„๋Š” ํ‘œ์ค€ JDBC ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐœ๋ฐœ์ž๋Š” ๋“œ๋ผ์ด๋ฒ„๋งŒ ๊ต์ฒดํ•˜๋ฉด DB ๋ณ€๊ฒฝ ์‹œ์—๋„ ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

6๏ธโƒฃ JDBC์˜ ํ•œ๊ณ„์™€ SQL ์ฐจ์ด

JDBC์˜ ํ•œ๊ณ„

  • JDBC๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„ SQL์˜ ์ฐจ์ด๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ณ„๋กœ ์ง€์›ํ•˜๋Š” SQL ๋ฌธ๋ฒ•์ด๋‚˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์‹ค๋ฌด์—์„œ์˜ SQL ์ฐจ์ด ์‚ฌ๋ก€

  • ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ SQL์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋งˆ๋‹ค ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
    • ์˜ˆ: MySQL์—์„œ๋Š” LIMIT์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, Oracle์—์„œ๋Š” ROWNUM์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

7๏ธโƒฃ JPA(Java Persistence API)์˜ ๋„์›€

  • JPA๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ณ„๋กœ ๋‹ค๋ฅธ SQL์„ ์ •์˜ํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.
  • JPA๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐ์ฒด ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๋ฉฐ, DB ๋ณ€๊ฒฝ ์‹œ์—๋„ SQL์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

2. JDBC์™€ ์ตœ์‹  ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ 

1๏ธโƒฃ JDBC๋ž€?

  • JDBC(Java Database Connectivity)*๋Š” 1997๋…„์— ์ถœ์‹œ๋œ ์˜ค๋ž˜๋œ ๊ธฐ์ˆ ๋กœ, ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๋Š” ํ‘œ์ค€ API์ž…๋‹ˆ๋‹ค.
  • ํ•˜์ง€๋งŒ, ์ง์ ‘ ์‚ฌ์šฉํ•˜๊ธฐ์—๋Š” ๋ณต์žกํ•˜๊ณ  ๋ฐ˜๋ณต ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„ ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ์ด ๋–จ์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

2๏ธโƒฃ JDBC๋ฅผ ๋Œ€์‹ ํ•˜๋Š” ์ตœ์‹  ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ 

1. SQL Mapper

  • SQL Mapper๋Š” JDBC๋ฅผ ๋ณด๋‹ค ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.
  • ์žฅ์ 
    • JDBC์˜ ๋ฐ˜๋ณต ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ๊ฐœ๋ฐœ ํŽธ์˜์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.
    • SQL ์‘๋‹ต ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹จ์ 
    • ๊ฐœ๋ฐœ์ž๊ฐ€ SQL์„ ์ง์ ‘ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฏ€๋กœ, SQL ์ž‘์„ฑ์— ๋Œ€ํ•œ ์ง€์‹์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ๋Œ€ํ‘œ ๊ธฐ์ˆ 
    • ์Šคํ”„๋ง JdbcTemplate
    • MyBatis

2. ORM(Object-Relational Mapping) ๊ธฐ์ˆ 

  • ORM ๊ธฐ์ˆ ์€ ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ๋งคํ•‘ํ•˜์—ฌ, SQL ์ž‘์„ฑ ์—†์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.
  • ์žฅ์ 
    • ๋ฐ˜๋ณต์ ์ธ SQL์„ ์ง์ ‘ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด, ORM ๊ธฐ์ˆ ์ด SQL์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฐ๊ฐ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋งˆ๋‹ค ๋‹ค๋ฅธ SQL ๋ฌธ๋ฒ• ๋ฌธ์ œ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด๊ฒฐํ•ด์ค๋‹ˆ๋‹ค.
    • ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.
  • ๋‹จ์ 
    • ์‚ฌ์šฉ์ด ํŽธ๋ฆฌํ•˜์ง€๋งŒ ๋ฐฐ์šฐ๊ธฐ ์–ด๋ ต๊ณ , ๊นŠ์ด ์žˆ๋Š” ํ•™์Šต์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    • ๋‚ด๋ถ€ ๋™์ž‘์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋ฉด, ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋Œ€์ฒ˜ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ๋Œ€ํ‘œ ๊ธฐ์ˆ 
    • JPA (Java Persistence API): ์ž๋ฐ” ์ง„์˜์˜ ORM ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค.
    • ํ•˜์ด๋ฒ„๋„ค์ดํŠธ: JPA์˜ ๋Œ€ํ‘œ์ ์ธ ๊ตฌํ˜„์ฒด.
    • ์ดํด๋ฆฝ์Šค๋งํฌ: JPA์˜ ๋˜ ๋‹ค๋ฅธ ๊ตฌํ˜„์ฒด.

3๏ธโƒฃ SQL Mapper์™€ ORM ๊ธฐ์ˆ  ๋น„๊ต

SQL Mapper

  • ์„ค๋ช…
    • SQL๋งŒ ์ง์ ‘ ์ž‘์„ฑํ•˜๋ฉด, ๋‚˜๋จธ์ง€ ์ž‘์—…์€ SQL Mapper๊ฐ€ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • SQL ์ž‘์„ฑ์— ๋Šฅ์ˆ™ํ•œ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ์‰ฝ๊ฒŒ ๋ฐฐ์›Œ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์žฅ์ 
    • SQL ์ž‘์„ฑ์— ๋Œ€ํ•œ ์ž์œ ๋„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค.
    • SQL์„ ์ง์ ‘ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹จ์ 
    • ์—ฌ์ „ํžˆ SQL์„ ์ง์ ‘ ์ž‘์„ฑํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋ณต ์ž‘์—…์ด ๋‚จ์•„์žˆ์Šต๋‹ˆ๋‹ค.

ORM ๊ธฐ์ˆ 

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

4๏ธโƒฃ ๋‚ด๋ถ€ ๋™์ž‘๊ณผ JDBC์˜ ์—ญํ• 

  • SQL Mapper์™€ ORM ๊ธฐ์ˆ  ๋ชจ๋‘ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” JDBC๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • JDBC๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ํ†ต์‹ ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•ต์‹ฌ ๊ธฐ์ˆ ๋กœ, ์ตœ์‹  ๊ธฐ์ˆ ๋“ค์ด ๋™์ž‘ํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ฐ˜์ด ๋ฉ๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ, JDBC์˜ ๊ธฐ๋ณธ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค:
    • ๊ธฐ์ˆ ์˜ ๋™์ž‘ ์›๋ฆฌ ์ดํ•ด: SQL Mapper๋‚˜ ORM์˜ ์ž‘๋™ ๋ฐฉ์‹์„ ๋” ๊นŠ์ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฌธ์ œ ํ•ด๊ฒฐ ๋Šฅ๋ ฅ ํ–ฅ์ƒ: JDBC ์›๋ฆฌ๋ฅผ ์•Œ๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๊ทผ๋ณธ์ ์ธ ์›์ธ์„ ์ฐพ์•„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5๏ธโƒฃ ๊ฒฐ๋ก 

  • SQL Mapper
    • SQL ์ž‘์„ฑ์— ๋Šฅ์ˆ™ํ•œ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ ํ•ฉํ•˜๋ฉฐ, SQL์„ ์ง์ ‘ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ORM ๊ธฐ์ˆ 
    • ๋ฐ˜๋ณต์ ์ธ SQL ์ž‘์—…์„ ์ œ๊ฑฐํ•˜์—ฌ ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€๊ฒฝ์— ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ทธ๋Ÿฌ๋‚˜ ํ•™์Šต ๊ณก์„ ์ด ๊ฐ€ํŒŒ๋ฅด๊ณ , ์„ฑ๋Šฅ ํŠœ๋‹์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • JDBC
    • ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ ์˜ ๊ธฐ๋ฐ˜์œผ๋กœ, ์ž๋ฐ” ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๋ฐ˜๋“œ์‹œ ์ดํ•ดํ•ด์•ผ ํ•  ํ•„์ˆ˜ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.

3. JDBC ์ดํ•ด ๋ฐ ํ™œ์šฉ ์ƒ์„ธ ์ •๋ฆฌ

1๏ธโƒฃ JDBC๋ฅผ ํ†ตํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ

1.1 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ๊ฐœ์š”

  • ๋Œ€๋ถ€๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(DB)์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ†ต์‹ ํ•˜๋ ค๋ฉด JDBC(Java Database Connectivity)์™€ ๊ฐ™์€ ํ‘œ์ค€ API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

1.2 H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์„ค์ •

  • H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์„œ๋ฒ„๋ฅผ ๋ฐ˜๋“œ์‹œ ์‹คํ–‰ํ•ด๋‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์— ํ•„์š”ํ•œ ์ •๋ณด๋Š” ์ƒ์ˆ˜๋กœ ์ •์˜ํ•˜์—ฌ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.
public abstract class ConnectionCost {
    public static final String URL = "jdbc:h2:tcp://localhost/~/test";
    public static final String USERNAME = "sa";
    public static final String PASSWORD = "";
}

1.3 DBConnectionUtil ํด๋ž˜์Šค

  • JDBC DriverManager๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ปค๋„ฅ์…˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

public class DBConnectionUtil {
    public static Connection getConnection() {
        try {
            Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            log.info("get connection={}, class={}", connection, connection.getClass());
            return connection;
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }
}
  • DriverManager๊ฐ€ ์ž‘๋™ํ•˜์—ฌ H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„์™€ ์—ฐ๊ฒฐํ•˜๊ณ , java.sql.Connection ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ JDBC์˜ ์ž‘๋™ ์›๋ฆฌ์™€ ํ๋ฆ„

2.1 DriverManager ์ปค๋„ฅ์…˜ ์š”์ฒญ ํ๋ฆ„

  1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์—์„œ ์š”์ฒญ:
    • DriverManager.getConnection() ํ˜ธ์ถœ.
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ด ํ˜ธ์ถœ์„ ํ†ตํ•ด DB ์—ฐ๊ฒฐ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  2. DriverManager์˜ ๋“œ๋ผ์ด๋ฒ„ ํƒ์ƒ‰:
    • DriverManager๋Š” ๋“ฑ๋ก๋œ ๋ชจ๋“  ๋“œ๋ผ์ด๋ฒ„๋ฅผ ํƒ์ƒ‰ํ•˜๋ฉฐ, URL๊ณผ ๋งค์นญ๋˜๋Š” ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
    • URL ์˜ˆ์‹œ: jdbc:h2:tcp://localhost/~/test.
  3. ์ ํ•ฉํ•œ ๋“œ๋ผ์ด๋ฒ„ ํ˜ธ์ถœ:
    • URL์ด jdbc:h2๋กœ ์‹œ์ž‘ํ•˜๋ฉด H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
    • ๋“œ๋ผ์ด๋ฒ„๋Š” ์ ์ ˆํ•œ ์ปค๋„ฅ์…˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  4. ์ปค๋„ฅ์…˜ ๋ฐ˜ํ™˜:
    • H2 ๋“œ๋ผ์ด๋ฒ„๋Š” org.h2.jdbc.JdbcConnection ๊ตฌํ˜„์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๊ตฌํ˜„์ฒด๋Š” ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค์ธ java.sql.Connection๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

3๏ธโƒฃ JDBC๋ฅผ ํ™œ์šฉํ•œ CRUD

3.1 ํšŒ์› ๋ฐ์ดํ„ฐ ๋“ฑ๋ก

ํšŒ์› ํ…Œ์ด๋ธ” ์ƒ์„ฑ

CREATE TABLE member (
    member_id VARCHAR(10),
    money INTEGER NOT NULL DEFAULT 0,
    PRIMARY KEY (member_id)
);

ํšŒ์› ๋ฐ์ดํ„ฐ ์ €์žฅ ์ฝ”๋“œ

  • ํšŒ์› ๋ฐ์ดํ„ฐ๋ฅผ INSERT SQL๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • JDBC์˜ PreparedStatement๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SQL๊ณผ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
public class MemberRepositoryV0 {
    public Member save(Member member) {
        String sql = "INSERT INTO member(member_id, money) VALUES(?, ?)";

        try (Connection con = getConnection();
             PreparedStatement pstmt = con.prepareStatement(sql)) {
            pstmt.setString(1, member.getMemberId());
            pstmt.setInt(2, member.getMoney());
            pstmt.executeUpdate(); // SQL ์‹คํ–‰
            return member;
        } catch (SQLException e) {
            log.error("DB Error", e);
            throw e;
        }
    }
}

 

๋ฆฌ์†Œ์Šค ์ •๋ฆฌ

  • ์‚ฌ์šฉํ•œ ๋ฆฌ์†Œ์Šค๋Š” ๋ฐ˜๋“œ์‹œ ๋‹ซ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • try-with-resources๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜, finally ๋ธ”๋ก์—์„œ ์ •๋ฆฌ ์ž‘์—… ์ˆ˜ํ–‰.

3.2 ํšŒ์› ๋ฐ์ดํ„ฐ ์กฐํšŒ

ํšŒ์› ์กฐํšŒ ์ฝ”๋“œ

  • ํšŒ์› ID๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋ฉฐ, ResultSet์„ ํ™œ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.
public Member findById(String memberId) {
    String sql = "SELECT * FROM member WHERE member_id = ?";
    try (Connection con = getConnection();
         PreparedStatement pstmt = con.prepareStatement(sql)) {
        pstmt.setString(1, memberId);

        try (ResultSet rs = pstmt.executeQuery()) {
            if (rs.next()) {
                return new Member(rs.getString("member_id"), rs.getInt("money"));
            } else {
                throw new NoSuchElementException("Member not found: " + memberId);
            }
        }
    } catch (SQLException e) {
        log.error("DB Error", e);
        throw e;
    }
}

ResultSet ๋™์ž‘

  • ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋Š” ResultSet์— ์ €์žฅ๋˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋Š” ์ปค์„œ๋ฅผ ํ†ตํ•ด ์ˆœ์ฐจ์ ์œผ๋กœ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • rs.next(): ์ปค์„œ๋ฅผ ๋‹ค์Œ ํ–‰์œผ๋กœ ์ด๋™ํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด true ๋ฐ˜ํ™˜.
    • rs.getString("column"): ํ•ด๋‹น ์ปฌ๋Ÿผ์˜ ๊ฐ’์„ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜.
    • rs.getInt("column"): ํ•ด๋‹น ์ปฌ๋Ÿผ์˜ ๊ฐ’์„ ์ •์ˆ˜๋กœ ๋ฐ˜ํ™˜.

3.3 ํšŒ์› ๋ฐ์ดํ„ฐ ์ˆ˜์ •

์ˆ˜์ • ์ฝ”๋“œ

  • ํŠน์ • ํšŒ์›์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” SQL์„ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ์„ ๋ฐ›์€ ํ–‰(row)์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
public void update(String memberId, int money) throws SQLException {
    String sql = "UPDATE member SET money=? WHERE member_id=?";
    try (Connection con = getConnection();
         PreparedStatement pstmt = con.prepareStatement(sql)) {
        pstmt.setInt(1, money);
        pstmt.setString(2, memberId);
        pstmt.executeUpdate(); // ์ˆ˜์ • SQL ์‹คํ–‰
    }
}

3.4 ํšŒ์› ๋ฐ์ดํ„ฐ ์‚ญ์ œ

์‚ญ์ œ ์ฝ”๋“œ

  • ํŠน์ • ํšŒ์› ID๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
public void delete(String memberId) throws SQLException {
    String sql = "DELETE FROM member WHERE member_id=?";
    try (Connection con = getConnection();
         PreparedStatement pstmt = con.prepareStatement(sql)) {
        pstmt.setString(1, memberId);
        pstmt.executeUpdate(); // ์‚ญ์ œ SQL ์‹คํ–‰
    }
}

4๏ธโƒฃ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

CRUD ํ…Œ์ŠคํŠธ

public class MemberRepositoryV0Test {
    MemberRepositoryV0 repository = new MemberRepositoryV0();

    @Test
    void crud() throws SQLException {
        // ํšŒ์› ๋“ฑ๋ก
        Member member = new Member("MemberV0", 10000);
        repository.save(member);

        // ํšŒ์› ์กฐํšŒ
        Member findMember = repository.findById(member.getMemberId());
        assertThat(findMember).isEqualTo(member);

        // ํšŒ์› ์ˆ˜์ •
        repository.update(member.getMemberId(), 20000);
        Member updatedMember = repository.findById(member.getMemberId());
        assertThat(updatedMember.getMoney()).isEqualTo(20000);

        // ํšŒ์› ์‚ญ์ œ
        repository.delete(member.getMemberId());
        assertThatThrownBy(() -> repository.findById(member.getMemberId()))
            .isInstanceOf(NoSuchElementException.class);
    }
}

5๏ธโƒฃ ์ฃผ์š” ๊ฐœ๋… ์š”์•ฝ

  1. JDBC DriverManager:
    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, URL ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ ์ ˆํ•œ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ฐพ์•„ ์ปค๋„ฅ์…˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜.
  2. PreparedStatement:
    • SQL์— ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ์ง€์›ํ•˜๋ฉฐ, SQL Injection ๋ฐฉ์ง€ ํšจ๊ณผ๊ฐ€ ์žˆ์Œ.
  3. ResultSet:
    • ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๋ฉฐ, ์ปค์„œ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ํƒ์ƒ‰.
  4. ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ:
    • Connection, PreparedStatement, ResultSet์„ ๋ฐ˜๋“œ์‹œ ๋‹ซ์•„์•ผ ํ•˜๋ฉฐ, ์ด๋ฅผ ๋ˆ„๋ฝํ•˜๋ฉด ๋ฆฌ์†Œ์Šค ๋ˆ„์ˆ˜ ๋ฐœ์ƒ ๊ฐ€๋Šฅ.