6์ฃผ์ฐจ ์๋ฃ์ ๋ชจ๋ ํ ํฝ์ ๋ ๊ฐ์ ํฐ ํ๋ฆ์ผ๋ก ์ ๋ฆฌํ ํ์ต ๊ฒฝ๋ก.
1) ํ์ต ๋๊ตฌ์ ํ๊ฒฝ โ JUnit ํ ์คํธ, ์น ์ธํ๋ผ(์๋ฒ/WAS/JAR/WAR)
2) DB ์ ๊ทผ์ ์งํ โ JDBC โ Connection Pool โ DataSource โ ํธ๋์ญ์ โ JdbcTemplate5์ฃผ์ฐจ์์ IoC/DI๋ฅผ ๋ฐฐ์ ๋ค๋ฉด, 6์ฃผ์ฐจ๋ ๊ทธ๊ฒ์ ํ ์คํธ๋ก ๊ฒ์ฆ ํ๊ณ ์นยทDB ํ๊ฒฝ์ผ๋ก ํ์ฅํ๋ค.
[Part A โ ํ์ต ๋๊ตฌ์ ํ๊ฒฝ]
[Phase 1] JUnit ํ
์คํธ
โ
[Phase 2] ์น ์ธํ๋ผ ๊ธฐ์ด (์น์๋ฒ/WAS/์๋ธ๋ฆฟ/JAR/WAR)
[Part B โ DB ์ ๊ทผ์ ์งํ] โ 6์ฃผ์ฐจ์ ์ ์
[Phase 3] JDBC ํ์คํ์ ๋ฑ์ฅ
โ
[Phase 4] Connection Pool๊ณผ DB ์ธ์
โ
[Phase 5] DataSource ์ธํฐํ์ด์ค (์ถ์ํ์ ์งํ)
โ
[Phase 6] ํธ๋์ญ์
๊ณผ ACID
โ
[Phase 7] JdbcTemplate (๋ฐ๋ณต ์ ๊ฑฐ)
์ด 7 Phase ร 28 Unit
| ์ฃผ์ฐจ | ์ฃผ์ | ํต์ฌ ๋ณํ |
|---|---|---|
| 1์ฃผ์ฐจ | OOPยทJVMยทGCยท์ปฌ๋ ์ ยทI/O ๊ฐ๋ก | ์๋ฐ ํฐ ๊ทธ๋ฆผ |
| 2์ฃผ์ฐจ | JVM ๋ด๋ถยท๋ฐ์ดํธ์ฝ๋ยทG1 GC | "์ด๋ป๊ฒ ๋์๊ฐ๋" |
| 3์ฃผ์ฐจ | ์ปฌ๋ ์ ยท์ ๋ค๋ฆญยทํจ์ํ | ์๋ฐ ํํ๋ ฅ |
| 4์ฃผ์ฐจ | ๋ฉํฐ์ค๋ ๋ฉยท๋์์ฑยทExecutor | ๋์์ฑ ์ ๋ณต |
| 5์ฃผ์ฐจ | Atomic + Spring IoC/DI ์ ๋ฌธ | ์๋ฐ โ Spring ๋ค๋ฆฌ |
| 6์ฃผ์ฐจ (์ง๊ธ) | ํ ์คํธ + ์น ์ธํ๋ผ + DB ์ ๊ทผ์ ์งํ | Spring ์ค์ ํ๊ฒฝ |
| Day | Phase | ํ์ต ๋ชฉํ |
|---|---|---|
| 1์ผ์ฐจ | Phase 1 | JUnit ํ ์คํธ ๋ง์คํฐ |
| 2์ผ์ฐจ | Phase 2 | ์น ์ธํ๋ผ ๊ธฐ์ด + JAR/WAR |
| 3์ผ์ฐจ | Phase 3 | JDBC์ ๋ณธ์ง ์ดํด |
| 4์ผ์ฐจ | Phase 4 | Connection Pool + DB ์ธ์ |
| 5์ผ์ฐจ | Phase 5 | DataSource ์ถ์ํ |
| 6์ผ์ฐจ | Phase 6 | ํธ๋์ญ์ ACID ์์ ์ ๋ณต |
| 7์ผ์ฐจ | Phase 7 | JdbcTemplate ์ค์ |
๋ชฉํ: 5์ฃผ์ฐจ์์ ๋ง๋ IoC/DI ์ฝ๋๋ฅผ ํ ์คํธ ์ฝ๋๋ก ๊ฒ์ฆํ๋ ๋ฐฉ๋ฒ์ ์ตํ๋ค. ํ ์คํธ ๊ฐ๋ฅํ ์ฝ๋ = ์ข์ ์ฝ๋ ๋ผ๋ ๋ช ์ ๋ฅผ ์ฒดํํ๋ค.
์ ์ ์ง์: 5์ฃผ์ฐจ Phase 8 (DI)
ํต์ฌ ๊ฐ๋
์ ํ ์คํธ์ธ๊ฐ:
์ข์ ๋จ์ ํ ์คํธ์ ์กฐ๊ฑด:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 1.1
ํต์ฌ ๊ฐ๋
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
assertThat(user2.getName(), is(user.getName()));
๊ตฌ์ฑ:
assertThat(actual, matcher): ์ฒซ ์ธ์(์ค์ ๊ฐ)๋ฅผ ๋งค์ฒ์ ๋น๊ตis(expected): equals ๋น๊ต ๋งค์ฒ (Hamcrest ๋ผ์ด๋ธ๋ฌ๋ฆฌ)์ ํต ๋ฐฉ์ vs Hamcrest:
// ์ ํต (JUnit 4)
assertEquals(user.getName(), user2.getName());
// Hamcrest ๋งค์ฒ
assertThat(user2.getName(), is(user.getName()));
์ฅ์ : ์์ฐ์ด์ฒ๋ผ ์ฝํ ("user2์ ์ด๋ฆ์ด user์ ์ด๋ฆ์ด๋ค")
์๊ธฐ ์ ๊ฒ
is() ์ธ์ ์์ฃผ ์ฐ๋ ๋งค์ฒ๋? (ํํธ: nullValue, containsString, greaterThan)assertEquals์ Hamcrest ์ค ๋ฌด์์ ์ธ๊น?์๋ณธ ์๋ฃ: ํ ๋น์ ์คํ๋ง vol.1, p.159
์ ์ ์ง์: Unit 1.2
ํต์ฌ ๊ฐ๋
JUnit์ด ํ ํ
์คํธ ํด๋์ค๋ฅผ ์ฒ๋ฆฌํ๋ 7๋จ๊ณ:
1. @Test๊ฐ ๋ถ์ public void ํ๋ผ๋ฏธํฐ ์๋ ๋ฉ์๋๋ฅผ ๋ชจ๋ ์ฐพ์
2. ํ
์คํธ ํด๋์ค์ ์ค๋ธ์ ํธ๋ฅผ ํ๋ ๋ง๋ฆ
3. @BeforeEach(๋๋ @Before) ๋ฉ์๋ ์คํ
4. @Test ๋ฉ์๋ ํ๋ ํธ์ถ, ๊ฒฐ๊ณผ ์ ์ฅ
5. @AfterEach ๋ฉ์๋ ์คํ
6. ๋๋จธ์ง ํ
์คํธ ๋ฉ์๋์ ๋ํด 2~5 ๋ฐ๋ณต
7. ๋ชจ๋ ๊ฒฐ๊ณผ ์ข
ํฉ ๋ฐํ
ํต์ฌ ํฌ์ธํธ: ๊ฐ ํ ์คํธ๋ง๋ค ์ ์ธ์คํด์ค ์์ฑ
์๊ธฐ ์ ๊ฒ
@BeforeAll ๊ณผ @BeforeEach ์ ์ฐจ์ด๋?์๋ณธ ์๋ฃ: ํ ๋น์ ์คํ๋ง vol.1, p.181
์ ์ ์ง์: Unit 1.3
ํต์ฌ ๊ฐ๋
"๊ฐ ํ ์คํธ๊ฐ ์๋ก ์ํฅ์ ์ฃผ์ง ์๊ณ ๋ ๋ฆฝ์ ์ผ๋ก ์คํ๋จ์ ํ์คํ ๋ณด์ฅํ๊ธฐ ์ํด"
์ป๋ ์ด์ :
์๊ธฐ ์ ๊ฒ
@BeforeAll)์๋ณธ ์๋ฃ: ํ ๋น์ ์คํ๋ง vol.1, p.182
์ ์ ์ง์: Unit 1.4
ํต์ฌ ๊ฐ๋
ํฝ์ค์ฒ(Fixture): ํ ์คํธ ์ํ์ ํ์ํ ์ ๋ณดยท์ค๋ธ์ ํธ
@BeforeEach๋ก ๋งค ํ
์คํธ ์ ์ ์๋ก ์์ฑpublic class UserDaoTest {
private UserDao dao; // ํฝ์ค์ฒ
@BeforeEach
public void setUp() {
ApplicationContext context = ...;
this.dao = context.getBean("userDao", UserDao.class);
}
@Test
public void test1() {
dao.add(...); // ํฝ์ค์ฒ ์ฌ์ฉ
}
}
ํ ์คํธ ๊ฒฐ๊ณผ์ ์ผ๊ด์ฑ:
dao.deleteAll() ๊ฐ์ด ์์ ์ํ ๋ณด์ฅ์๊ธฐ ์ ๊ฒ
@Transactional, @Sql)๋ชฉํ: Spring MVC ํ์ต ์ , ์น ๋ฐฑ์๋์ ๊ธฐ๋ณธ ์ธํ๋ผ ์ฉ์ด๋ฅผ ์ ๋ฆฌํ๋ค. ๋ชจ๋ฅด๋ฉด ๋ฉด์ ยท์ค๋ฌด ๋ชจ๋์์ ํค๋งจ๋ค.
์ ์ ์ง์: 1์ฃผ์ฐจ Phase 7 (I/O)
ํต์ฌ ๊ฐ๋
| ๊ตฌ๋ถ | ์น์๋ฒ | WAS |
|---|---|---|
| ์ญํ | ์ ์ ์์ (HTML, CSS, ์ด๋ฏธ์ง) ์ ๊ณต | ๋์ ์์ (์๋ธ๋ฆฟ, JSP) ์ฒ๋ฆฌ |
| ์์ | Apache, Nginx | Tomcat, Jetty, Undertow |
| ์ฒ๋ฆฌ | ํ์ผ ๊ทธ๋๋ก ์๋ต | ์ฝ๋ ์คํ โ ๊ฒฐ๊ณผ ์๋ต |
์ค๋ฌด ๊ตฌ์ฑ:
[ํด๋ผ์ด์ธํธ] โ [Nginx (์น์๋ฒ)] โ [Tomcat (WAS)] โ [DB]
์ ์ ํ์ผ ์ฒ๋ฆฌ ๋์ ์์ฒญ๋ง ์์
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.1
ํต์ฌ ๊ฐ๋
์๋ธ๋ฆฟ(Servlet):
JSP (Java Server Pages):
์ญํ ๋ถ๋ด์ ์งํ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.2
ํต์ฌ ๊ฐ๋
| ๊ตฌ๋ถ | SSR (Server Side Rendering) | CSR (Client Side Rendering) |
|---|---|---|
| ํ๋ฉด ์์ฑ | ์๋ฒ์์ HTML ์์ฑ | ๋ธ๋ผ์ฐ์ (JS)๊ฐ ํ๋ฉด ๊ทธ๋ฆผ |
| ์ด๊ธฐ ๋ก๋ฉ | ๋น ๋ฆ | ๋๋ฆผ (JS ๋ค์ด๋ก๋ ํ์) |
| SEO | ์ข์ | ๊น๋ค๋ก์ |
| ์๋ฒ ๋ถํ | ํผ | ์์ (JSON๋ง) |
| ์์ | JSP, Thymeleaf, Next.js (SSR) | React SPA, Vue SPA |
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.2
ํต์ฌ ๊ฐ๋
| JAR | WAR | |
|---|---|---|
| ์ ์ ๋ช ์นญ | Java Archive | Web Application Archive |
| ํฌํจ | Class, ๋ผ์ด๋ธ๋ฌ๋ฆฌ | + JSP, Servlet, WEB-INF, META-INF |
| ์คํ ํ๊ฒฝ | JRE๋ง ์์ผ๋ฉด OK | ์ธ๋ถ WAS ํ์ |
| ์คํ | java -jar app.jar | Tomcat ๋ฑ์ ๋ฐฐํฌ |
| ๊ตฌ์กฐ | ์์ | ์ฌ์ ์ ์๋ ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ |
Spring Boot์ ์ ํ: JAR
WAR๊ฐ ํ์ํ ๊ฒฝ์ฐ:
์๊ธฐ ์ ๊ฒ
BOOT-INF/lib)์ด ํํธ์ ํฐ ๊ทธ๋ฆผ:
"DB ์ฝ๋ ํ ์ค์ด ์ด๋ป๊ฒ JdbcTemplate๊น์ง ์งํํ๋์ง" โ 5์ฃผ์ฐจ์ DAO ์งํ์ ์ด์ด, ์ด๋ฒ์ DB ์ ๊ทผ ์์ฒด์ ์ถ์ํ ์ฌ์ ์ ๋ฐ๋ผ๊ฐ๋ค.
๋ชฉํ: JDBC๊ฐ ์ ๋ฑ์ฅํ๋์ง, ์ด๋ค ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ด๋ค ๋ฌธ์ ๋ ์ ํด๊ฒฐํ๋์ง ๋ช ํํ ํ๋ค.
์ ์ ์ง์: Phase 2
ํต์ฌ ๊ฐ๋
JDBC ๋ฑ์ฅ ์ :
์์ (JDBC ์์ ๋):
// ์ง์ ์์ผ์ผ๋ก MySQL ํ๋กํ ์ฝ๊ณผ ํต์
Socket socket = new Socket("localhost", 3306);
DataOutputStream out = new DataOutputStream(...);
out.writeUTF("Handshake request to MySQL server");
// MySQL์ ๋ฐ์ด๋๋ฆฌ ํ๋กํ ์ฝ์ ์ง์ ์์์ผ ํจ
โ ๊ฐ๋ฐ์๊ฐ DB ํ๋กํ ์ฝ๊น์ง ์์์ผ ํ๋ ์ง์ฅ
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 3.1
ํต์ฌ ๊ฐ๋
JDBC = ์๋ฐ์ DB ์ ๊ทผ ํ์ค API
๊ฐ์ ์ฝ๋, ๋ค๋ฅธ DB:
// MySQL
String url = "jdbc:mysql://localhost:3306/mydb";
// Oracle
String url = "jdbc:oracle:thin:@localhost:1521:xe";
// PostgreSQL
String url = "jdbc:postgresql://localhost:5432/mydb";
// ์ดํ ๋ชจ๋ ์ฝ๋๋ ๋์ผ!
Connection conn = DriverManager.getConnection(url, user, pwd);
PreparedStatement ps = conn.prepareStatement("SELECT ...");
ResultSet rs = ps.executeQuery();
JDBC๊ฐ ํด๊ฒฐํ ๊ฒ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 3.2
ํต์ฌ ํ๊ณ
JDBC๋ API๋ ํต์ผ ํ์ง๋ง, SQL ๋ฌธ๋ฒ ์ฐจ์ด๋ ๊ทธ๋๋ก:
ํด๊ฒฐ: ์์ ํ๋ ์์ํฌ ์ฌ์ฉ
์๊ธฐ ์ ๊ฒ
๋ชฉํ: "์ ๋งค๋ฒ ์๋ก ์ฐ๊ฒฐํ๋ฉด ์ ๋๋๊ฐ" ๋ผ๋ ๊ทผ๋ณธ ์ง๋ฌธ์ TCP/IP ๋ ๋ฒจ๋ก ๋ตํ ์ ์๊ฒ ๋๋ค.
์ ์ ์ง์: Phase 3
ํต์ฌ ๊ฐ๋
DB ์ฐ๊ฒฐ์ ๋น์ฉ:
1. TCP/IP 3-way handshake (๋คํธ์ํฌ ์๋ณต)
2. DB ์ธ์ฆ (ID/PW ๊ฒ์ฆ)
3. DB๊ฐ ์ธ์
์์ฑ
โ ๋งค ์์ฒญ๋ง๋ค ์ด๊ฑธ ๋ค ํ๋ฉด?
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 4.1
ํต์ฌ ๊ฐ๋
"Connection์ ์์์ฅ"
๋์ ๋ฐฉ์:
1. ์ ํ๋ฆฌ์ผ์ด์
์์ ์ N๊ฐ์ Connection ๋ฏธ๋ฆฌ ์์ฑ
2. ์์ฒญ ์: ํ์์ ๋น๋ ค์ด
3. ์ฌ์ฉ ํ: ํ์ ๋ฐํ
4. ํ์ Connection์ ์ฌ์ฌ์ฉ
[์์ฒญ1] โโ> [Pool์์ Conn1 ๋น๋ฆผ] โโ> [DB ์์
] โโ> [Conn1 ๋ฐํ]
[์์ฒญ2] โโ> [Pool์์ Conn2 ๋น๋ฆผ] โโ> [DB ์์
] โโ> [Conn2 ๋ฐํ]
...
๋ํ ๊ตฌํ์ฒด:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 4.2
ํต์ฌ ๊ฐ๋
์ฐ๊ฒฐ ์ ์ฐจ:
1. ํด๋ผ์ด์ธํธ โ DB ์๋ฒ์ ์ฐ๊ฒฐ ์์ฒญ (TCP ์ฐ๊ฒฐ)
2. DB๊ฐ ์ธ์
์์ฑ (ํธ๋์ญ์
๋จ์)
3. ํด๋ผ์ด์ธํธ๊ฐ SQL ์ ๋ฌ โ ์ธ์
์ด ์คํ
4. ์ธ์
์ด ํธ๋์ญ์
์์ โ commit/rollback์ผ๋ก ์ข
๋ฃ
5. ์ฌ์ฉ์๊ฐ ์ปค๋ฅ์
๋ซ๊ฑฐ๋ DB ๊ด๋ฆฌ์๊ฐ ์ธ์
์ข
๋ฃ
์ค์ํ ๋งคํ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 4.3
ํต์ฌ ๊ฐ๋
์ ๋ฝ์ด ํ์ํ๊ฐ:
ํด๊ฒฐ: ํธ๋์ญ์ ์งํ ์ค์๋ ๋ค๋ฅธ ์ธ์ ์ด ํด๋น ๋ฐ์ดํฐ๋ฅผ ์์ ๋ชป ํ๋๋ก ๋ฝ
๋ฝ์ ์ข ๋ฅ (๊ฐ๋ต):
์๊ธฐ ์ ๊ฒ
๋ชฉํ: 5์ฃผ์ฐจ์ ์ธํฐํ์ด์ค ์ถ์ํ ์ ์ ์ด ์๋ฐ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ด๋ป๊ฒ ๋ น์์๋์ง ๋ณธ๋ค.
์ ์ ์ง์: Phase 4
ํต์ฌ ๊ฐ๋
์ปค๋ฅ์ ์ ์ป๋ ๋ฐฉ๋ฒ์ ๋ค์:
DriverManager.getConnection() โ ๋งค๋ฒ ์๋ก ๋ง๋ฆ (ํ X)HikariCP โ ์ปค๋ฅ์
ํDBCP2 โ ์ปค๋ฅ์
ํTomcat JDBC Pool โ ์ปค๋ฅ์
ํ๋ฌธ์ :
// DriverManager ์ฌ์ฉ ์ฝ๋
Connection c = DriverManager.getConnection(url, user, pwd);
// HikariCP๋ก ๋ณ๊ฒฝ ์
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(url); ...
Connection c = ds.getConnection(); // โ ์ฌ์ฉ๋ฒ์ด ๋ค๋ฆ!
โ ์ปค๋ฅ์ ํ๋ ๋ฐฉ๋ฒ์ด ๋ฐ๋๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋๊ฐ ๋ค ๋ฐ๋๋ค
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.1
ํต์ฌ ํต์ฐฐ
5์ฃผ์ฐจ์์ ๋ณธ OCP ์ ์ ๊ณผ ๊ฐ์ ๋ฌธ์ :
ํด๊ฒฐ์ ๋ฐฉํฅ:
"์ปค๋ฅ์ ์ ์ป๋ ๋ฐฉ๋ฒ" ์์ฒด๋ฅผ ์ธํฐํ์ด์ค๋ก ๋ถ๋ฆฌ
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.2
ํต์ฌ ๊ฐ๋
javax.sql.DataSource โ ์๋ฐ ํ์ค ์ธํฐํ์ด์ค
public interface DataSource {
Connection getConnection() throws SQLException;
// ... ๊ธฐํ
}
ํต์ฌ ๋ฉ์๋๋ getConnection() ํ๋.
๊ตฌํ์ฒด๋ค:
HikariDataSource (HikariCP)BasicDataSource (DBCP2)DriverManagerDataSource (Spring ์ ๊ณต, ํ ์์)์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋:
@Autowired
private DataSource dataSource; // ์ธํฐํ์ด์ค์ ์์กด
public void something() {
Connection c = dataSource.getConnection(); // ์ด๋ค ๊ตฌํ์ฒด๋ OK
// ...
}
HikariCP โ DBCP2 ๋ณ๊ฒฝ ์: ์ค์ ํ์ผ๋ง ๋ณ๊ฒฝ, ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋๋ ๊ทธ๋๋ก.
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.3
ํต์ฌ ๊ฐ๋
๋ฌธ์ : DriverManager๋ DataSource๋ฅผ ๊ตฌํํ์ง ์์
Spring์ ํด๊ฒฐ: DriverManagerDataSource
์ฉ๋:
ํ๋ก๋์ ์์๋ ์ ๋ ์ฐ์ง ๋ง ๊ฒ (ํ์ด ์์ด์ ์ฑ๋ฅ ํญ๋ง)
์๊ธฐ ์ ๊ฒ
๋ชฉํ: DB ํธ๋์ญ์ ์ 4๊ฐ์ง ํต์ฌ ์ฑ์ง์ ์ค์ํ ์์ ๋ก ์ฒดํํ๊ณ , ๋ฉํฐ ์ธ์ ํ๊ฒฝ์์์ ๋์์ ๋ณธ๋ค.
์ ์ ์ง์: Phase 4
ํต์ฌ ๊ฐ๋
"ํ ๋จ์์ ์์ ์ผ๋ก ์ทจ๊ธ๋๋ ๋ชจ๋ ์์ "
๊ณ์ข ์ด์ฒด ์์:
ํธ๋์ญ์ ์ ๋:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 6.1
ํต์ฌ ๊ฐ๋
"ํธ๋์ญ์ ์ ๋ชจ๋ ์ฐ์ฐ์ด ๋ชจ๋ ์ฑ๊ณต ํ๊ฑฐ๋ ๋ชจ๋ ์คํจ ํด์ผ ํ๋ค"
๊ณ์ข ์ด์ฒด ์๋๋ฆฌ์ค:
4์ฃผ์ฐจ์ ์๋ฐ Atomic๊ณผ ๋ค๋ฅธ ์ :
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 6.2
ํต์ฌ ๊ฐ๋
"ํธ๋์ญ์ ์๋ฃ ํ DB ์ ์ฝ์กฐ๊ฑด์ด ํญ์ ์ง์ผ์ ธ์ผ ํ๋ค"
์์:
์ ์ฝ์กฐ๊ฑด์ ์ข ๋ฅ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 6.3
ํต์ฌ ๊ฐ๋
"๊ฐ ํธ๋์ญ์ ์ ๋ค๋ฅธ ํธ๋์ญ์ ๊ณผ ๋ ๋ฆฝ์ ์ผ๋ก ์คํ๋์ด์ผ ํ๋ค"
์์:
๊ฒฉ๋ฆฌ ์์ค (๊ฐ๋ต):
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 6.4
ํต์ฌ ๊ฐ๋
"Commit๋ ํธ๋์ญ์ ์ DB์ ์๊ตฌ ๋ณด์กด ๋์ด์ผ ํ๋ค"
๋ณด์ฅ ์๋จ:
์์คํ ์ด ๋ค์ด๋์ด๋ ์ปค๋ฐ๋ ๋ฐ์ดํฐ๋ ์ด์์์ด์ผ ํ๋ค.
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 6.5
ํต์ฌ ์๋๋ฆฌ์ค
์ธ์
1: ๋ฐ์ดํฐ ๋ณ๊ฒฝ (commit X)
์ธ์
2: ๊ฐ์ ๋ฐ์ดํฐ ์กฐํ
๊ฒฐ๊ณผ:
๋น์ :
์๊ธฐ ์ ๊ฒ
๋ชฉํ: JDBC ์ฝ๋์ ๋์ฐํ ๋ฐ๋ณต์ Spring์ด ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง ๋ณธ๋ค.
์ ์ ์ง์: Phase 3
ํต์ฌ ๋ฌธ์
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = ...;
stmt = conn.prepareStatement(sql);
stmt.setInt(1, age);
rs = stmt.executeQuery();
while (rs.next()) {
// ๊ฒฐ๊ณผ ์ฒ๋ฆฌ
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) try { rs.close(); } catch (...) { ... }
if (stmt != null) try { stmt.close(); } catch (...) { ... }
if (conn != null) try { conn.close(); } catch (...) { ... }
}
๋ฌธ์ :
5์ฃผ์ฐจ์์ ๋ณธ ํจํด:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 7.1
ํต์ฌ ๊ฐ๋
JdbcTemplate = 5์ฃผ์ฐจ์์ ๋ณธ ํ ํ๋ฆฟ ๋ฉ์๋ + ์ ๋ต ํจํด์ ์ค์ ๊ตฌํ
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Customer> getCustomersByAge(int age) {
String sql = "SELECT * FROM customers WHERE age > ?";
return jdbcTemplate.query(sql, new Object[]{age},
new BeanPropertyRowMapper<>(Customer.class));
}
์จ๊ฒจ์ง ๊ฒ:
๊ฐ๋ฐ์๋ ๋ณํ๋ ๋ถ๋ถ๋ง:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 7.2
ํต์ฌ ๋ฉ์๋
| ๋ฉ์๋ | ์ฉ๋ | ๋ฐํ |
|---|---|---|
update(sql, params) | INSERT / UPDATE / DELETE | ์ํฅ๋ฐ์ ํ ์ |
queryForObject(sql, mapper, params) | ๋จ์ผ ํ ์กฐํ | ๊ฐ์ฒด 1๊ฐ |
query(sql, mapper, params) | ์ฌ๋ฌ ํ ์กฐํ | List<๊ฐ์ฒด> |
execute(sql) | ์์ SQL (DDL ๋ฑ) | void |
์์:
// UPDATE
jdbcTemplate.update(
"UPDATE item SET price=? WHERE id=?",
newPrice, itemId
);
// ๋จ์ผ ํ
Item item = jdbcTemplate.queryForObject(
"SELECT * FROM item WHERE id=?",
itemRowMapper, id
);
// ์ฌ๋ฌ ํ
List<Item> items = jdbcTemplate.query(
"SELECT * FROM item",
itemRowMapper
);
// DDL
jdbcTemplate.execute(
"CREATE TABLE mytable (id INT, name VARCHAR(100))"
);
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 7.3
ํต์ฌ ๊ฐ๋
RowMapper: ResultSet์ ํ ํ โ ์๋ฐ ๊ฐ์ฒด๋ก ๋งคํ
์ ํต JDBC:
while (rs.next()) {
User user = new User();
user.setId(rs.getInt(1));
user.setName(rs.getString(2));
userList.add(user);
}
RowMapper ์ฌ์ฉ:
RowMapper<Item> itemRowMapper = (rs, rowNum) -> {
Item item = new Item();
item.setId(rs.getLong("id"));
item.setItemName(rs.getString("item_name"));
return item;
};
// ์ฌ์ฉ
Item item = jdbcTemplate.queryForObject(sql, itemRowMapper, id);
List<Item> items = jdbcTemplate.query(sql, itemRowMapper);
๋๋ค์ ์ ๋ง์ (ํจ์ํ ์ธํฐํ์ด์ค):
RowMapper<Item> mapper = (rs, n) -> new Item(...);
BeanPropertyRowMapper โ ์๋ ๋งคํ:
new BeanPropertyRowMapper<>(Item.class)
// SQL ์ปฌ๋ผ๋ช
๊ณผ ์๋ฐ ํ๋๋ช
์ด ๊ฐ์ผ๋ฉด ์๋ ๋งคํ
// item_name โ itemName ์ฒ๋ผ snake โ camel ๋ณํ๋ ๋จ
์๊ธฐ ์ ๊ฒ
RowMapper๊ฐ ํจ์ํ ์ธํฐํ์ด์ค์ธ ๊ฒ ์ด๋ค ์ด์ ์ ์ฃผ๋๊ฐ? (ํํธ: 3์ฃผ์ฐจ ๋๋ค)์ ์ ์ง์: Unit 7.4
ํต์ฌ ํต์ฐฐ
JdbcTemplate์ 5์ฃผ์ฐจ์์ ๋ฐฐ์ด ๋ชจ๋ ์์น์ ์ง์ฝ์ฒด:
| ์์น/ํจํด | JdbcTemplate์์์ ์ ์ฉ |
|---|---|
| ๊ด์ฌ์ฌ ๋ถ๋ฆฌ | SQL/๋งคํ โ ์์ ๊ด๋ฆฌ ๋ถ๋ฆฌ |
| ํ ํ๋ฆฟ ๋ฉ์๋ ํจํด | ๋ณํ์ง ์๋ ํ๋ฆ์ด ํ ํ๋ฆฟ ์ |
| ์ ๋ต ํจํด | RowMapper, PreparedStatementSetter |
| OCP | ์ ๋งคํ ์ถ๊ฐ ์ ๊ธฐ์กด ์ฝ๋ ๋ณ๊ฒฝ X |
| DI | DataSource๋ฅผ ์ธ๋ถ์์ ์ฃผ์ ๋ฐ์ |
| ๋๋ค ํ์ฉ (3์ฃผ์ฐจ) | RowMapper๋ฅผ ๋๋ค๋ก |
โ "Spring์ ๋ฐฐ์ฐ๋ฉด OOP์ ์ข์ ์ฌ๋ก๊ฐ ๋ณด์ธ๋ค"
์๊ธฐ ์ ๊ฒ
@BeforeEach ์ @BeforeAll ์ ์ฐจ์ด๋?๋ฐ๋์ ๊น์ด ํ๊ธฐ:
[ ] Phase 1 โ JUnit ํ
์คํธ (Unit 1.1~1.5)
[ ] Phase 2 โ ์น ์ธํ๋ผ ๊ธฐ์ด (Unit 2.1~2.4)
[ ] Phase 3 โ JDBC ํ์คํ (Unit 3.1~3.3)
[ ] Phase 4 โ Connection Pool๊ณผ DB ์ธ์
(Unit 4.1~4.4)
[ ] Phase 5 โ DataSource ์ธํฐํ์ด์ค (Unit 5.1~5.4)
[ ] Phase 6 โ ํธ๋์ญ์
ACID (Unit 6.1~6.6)
[ ] Phase 7 โ JdbcTemplate (Unit 7.1~7.5)
[ ] ์ข
ํฉ ์๊ธฐ ์ ๊ฒ 25๋ฌธํญ ํต๊ณผ
5์ฃผ์ฐจ์์ ๋ฐฐ์ด ๋์์ธ ์์น์ด ์ด๋ฒ ์ฃผ์ ์ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ด๋ป๊ฒ ๊ตฌํ๋์๋์ง ์ถ์ ํด๋ณด์ธ์:
| 5์ฃผ์ฐจ ๊ฐ๋ | 6์ฃผ์ฐจ์์์ ๊ตฌํ |
|---|---|
| ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ | DataSource (์ปค๋ฅ์ ํ๋๊ณผ ์ฌ์ฉ ๋ถ๋ฆฌ) |
| ํ ํ๋ฆฟ ๋ฉ์๋ / ์ ๋ต ํจํด | JdbcTemplate |
| OCP | DataSource๋ก ํ ๊ตฌํ ๊ต์ฒด ๊ฐ๋ฅ |
| DI | @Autowired DataSource |
โ "์ข์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ข์ OOP ์์น์ ์ง์ฝ์ฒด๋ค" ๊ฐ 6์ฃผ์ฐจ์ ๋ฉ์์ง.