JDBC API๋ฅผ ๊ฐํธํ๊ฒ โ JDBC Template

๐ Spring JDBC : ๊ฐํธํ JDBC API ์ฌ์ฉ์ ์ํ JDBC Template ์ ๊ณต
Spring JDBC๋ ๋ฐ๋ณต์ ์ธ JDBC API ์ฝ๋๋ฅผ ๊ฐ์ํํ์ฌ ํจ์จ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ์ง์ํ๋ค.
JDBC API๋ฅผ ์ฌ์ฉํ ๋ ๋ฐ์ํ๋ ๊ตฌ์กฐ์ ๋ฐ๋ณต ๋ฌธ์ ์ ์์ธ ์ฒ๋ฆฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Spring์ด JdbcTemplate์ ์ ๊ณตํ๋ค.


1๏ธโฃ Spring JDBC๊ฐ ํด๊ฒฐํ๋ ๋ฌธ์
1-1. ๋ฐ๋ณต๋๋ ์ฝ๋ ์ ๊ฑฐ
JDBC API๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฐ๋ณต ์์ ์ด ๋ฐ์ํ๋ค.
- Connection ๊ฐ์ฒด ์์ฑ ๋ฐ ๋ฐํ
- Statement ์์ฑ ๋ฐ ์คํ
- ResultSet ์ฒ๋ฆฌ
- ์์ธ์ฒ๋ฆฌ์ ์์ ์ ๋ฆฌ
JdbcTemplate์ ์ด ๋ชจ๋ ๊ณผ์ ์ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ๊ฐ๋จํ๊ณ ๊น๋ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋๋ก ๋์์ค๋ค.
1-2. ์์ธ ์ฒ๋ฆฌ ๊ฐ์ํ
- JDBC API๋ SQLException๊ณผ ๊ฐ์ ์์ธ๋ฅผ try-catch-finally ๋ธ๋ก์ผ๋ก ์ฒ๋ฆฌํด์ผ ํ๋ค.
- JdbcTemplate์ ์์ธ๋ฅผ Spring์ DataAccessException์ผ๋ก ๋ณํํ์ฌ ์ฒ๋ฆฌ ๊ณผ์ ์ ๋จ์ํ์ํจ๋ค.
1-3. ๊ฐ๋จํ ํธ๋์ญ์ ์ฒ๋ฆฌ
- JDBC API์์ ๋ค์์ ์ฟผ๋ฆฌ๋ฅผ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ๋ฌถ์ผ๋ ค๋ฉด ์๋์ผ๋ก Connection ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌํด์ผ ํ๋ค.
- Spring์์๋ ํธ๋์ญ์ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํด ๊ฐํธํ๊ฒ ํธ๋์ญ์ ์ ๊ด๋ฆฌํ๋ค.
2๏ธโฃ Spring JDBC: JdbcTemplate
๊ธฐ์กด์ ์ฝ๋์ธ JDBC API(https://1000sang-dev.tistory.com/79)๋ฅผ JdbcTemplate์ผ๋ก Repository ๊ตฌํ.
โป Service ๋ก์ง๋ JdbcTemplate์ ๋ง๊ฒ ์์ ํด ์ค๋ค. (์ฝ๋๋ ๋ฐ๋ก ์์ฌ๋ฆผ)
2-1. JdbcTemplate์ผ๋ก ๋จ์ผ SELECT ์ํ
JdbcTemplate๋ JDBC API์ ์ฃผ์ ๊ตฌ์ฑ ์์๋ฅผ ๊ฐ์ํํ์ฌ ์ ๊ณตํ๋ค.
@Repository
@RequiredArgsConstructor
public class UserJdbcTemplateDao {
private final JdbcTemplate jdbcTemplate;
public User findById(int userId) {
String getUserQuery = "SELECT * FROM \"user\" WHERE id = ?";
int getUserParams = userId;
return this.jdbcTemplate.queryForObject(
getUserQuery,
(resultSet, rowNum) -> new User(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getInt("age"),
resultSet.getString("job"),
resultSet.getString("specialty"),
resultSet.getTimestamp("created_at")
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
),
getUserParams
);
}
}
- queryForObject ๋ฉ์๋
- SQL ์ฟผ๋ฆฌ
- RowMapper: ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ ๋๋ค ํจ์ (ํน์ RowMapper ๊ตฌํ์ฒด)
- ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ
2-2. JdbcTemplate์ผ๋ก ๋ค์ SELECT ์ํ
@Repository
@RequiredArgsConstructor
public class UserJdbcTemplateDao {
private final JdbcTemplate jdbcTemplate;
public List<User> findAll() {
String getUserQuery = "SELECT * FROM \"user\"";
return this.jdbcTemplate.queryForStream(
getUserQuery,
(resultSet, rowNum) -> new User(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getInt("age"),
resultSet.getString("job"),
resultSet.getString("specialty"),
resultSet.getTimestamp("created_at")
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
)
).toList();
}
}
- queryForStream
- SQL ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ Java 8+์ Stream ํํ๋ก ๋ฐํํด์ค๋ค.
2-3. JdbcTemplate์ผ๋ก INSERT ์ํ
public User save(String name, Integer age, String job, String specialty) {
// (A) INSERT USER
String createUserQuery = "INSERT INTO \"user\" (name, age, job, specialty, created_at) VALUES (?, ?, ?, ?, ?)";
Object createUserParams = new Object[]{
name,
age,
job,
specialty,
LocalDateTime.now()
};
this.jdbcTemplate.update(
createUserQuery,
createUserParams,
int.class
);
// (B) SELECT id - MySQL:last_insert_id()->id / PostgresQL:currval()->lastval/lastval()->lastval
String lastInsertIdQuery = "SELECT lastval()";
int createdUserId = this.jdbcTemplate.queryForObject(
lastInsertIdQuery,
int.class
);
// (C) SELECT USER
String getUserQuery = "SELECT * FROM \"user\" WHERE id = ?";
int getUserParams = createdUserId;
return this.jdbcTemplate.queryForObject(
getUserQuery,
(resultSet, rowNum) -> new User(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getInt("age"),
resultSet.getString("job"),
resultSet.getString("specialty"),
resultSet.getTimestamp("created_at")
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
),
getUserParams
);
}
- update
- ๋จ์ผ ๋ฐ์ดํฐ ์ฝ์ ๋ฐ ์กฐ์
2-4. JdbcTemplate์ผ๋ก UPDATE ์ํ
public User update(int id, String name, Integer age, String job, String specialty) {
// (A) UPDATE USER
String updateUserQuery = "UPDATE \"user\" SET name = ?, age = ?, job = ?, specialty = ? WHERE id = ?";
Object[] updateUserParams = new Object[]{
name,
age,
specialty,
id,
};
int rowsAffected = this.jdbcTemplate.update(
updateUserQuery,
updateUserParams
);
// (B) SELECT USER
String getUserQuery = "SELECT * FROM \"user\" WHERE id = ?";
int getUserParams = id;
return this.jdbcTemplate.queryForObject(
getUserQuery,
(resultSet, rowNum) -> new User(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getInt("age"),
resultSet.getString("job"),
resultSet.getString("specialty"),
resultSet.getTimestamp("created_at")
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
),
getUserParams
);
}
}
2-5. JdbcTemplate์ผ๋ก DELETE ์ํ
public void delete(int userId) {
String deleteUserQuery = "DELETE FROM \"user\" WHERE id = ?";
Object[] deleteUserParams = new Object[]{
userId
};
this.jdbcTemplate.update(
deleteUserQuery,
deleteUserParams
);
}
3๏ธโฃ JdbcTemplate ์ฅ์
1. ์ฝ๋ ๊ฐ์ํ
- ๋ณต์กํ JDBC API ์ฝ๋๋ฅผ ์ ๊ฑฐํ์ฌ ๊ฐ๊ฒฐํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ฝ๋ ์์ฑ ๊ฐ๋ฅ.
2. ์์ธ ์ฒ๋ฆฌ ํต์ผ
- Spring์ DataAccessException์ผ๋ก ์์ธ๋ฅผ ํตํฉ ๊ด๋ฆฌ.
3. ํธ๋์ญ์ ๊ด๋ฆฌ ํตํฉ
- Spring์ ํธ๋์ญ์ ๊ด๋ฆฌ์๋ฅผ ํ์ฉํด ์์ฝ๊ฒ ํธ๋์ญ์ ์ฒ๋ฆฌ ๊ฐ๋ฅ.
4. ๋ฐ๋ณต ์์ ์ ๊ฑฐ
- Connection ์์ฑ, ์์ ๋ฐํ, SQLException ์ฒ๋ฆฌ ๋ฑ ๋ฐ๋ณต ์์ ์ด ํ์ ์์.
4๏ธโฃ ํธ๋์ญ์ ์ฒ๋ฆฌ
Spring์์๋ PlatformTransactionManager์ @Transactional์ ์ฌ์ฉํ์ฌ ํธ๋์ญ์ ์ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค
ํธ๋์ญ์ ์ฃผ์ ๊ฐ๋
- ํธ๋์ญ์ ์์ฑ: Connection ์์ฑ
- ํธ๋์ญ์ ์ฐธ์ฌ: ๋์ผ Connection์์ ์์ ์ํ
- ํธ๋์ญ์ ์ฒ๋ฆฌ: ์ ์ ์ข ๋ฃ ์ Commit, ์์ธ ๋ฐ์ ์ RollBack

5๏ธโฃ JdbcTemplate ์ฌ์ฉ ์ ์ฃผ์ ์ฌํญ
1. DataSource ์ค์
- JdbcTemplate๋ ๋ด๋ถ์ ์ผ๋ก DataSource๋ฅผ ์ฌ์ฉํ๋ฏ๋ก, ์ ์ ํ ์ค์ ๋ DataSource๊ฐ ํ์ํ๋ค.
2. ํธ๋์ญ์ ์ปจํ ์คํธ
- @Transactional ์ฌ์ฉ ์ ๋ชจ๋ ์ฟผ๋ฆฌ๊ฐ ๋์ผ Connection์์ ์คํ๋๋๋ก ๋ณด์ฅ๋๋ค.
3. Connection ๊ด๋ฆฌ
- Spring์ Connection์ ์๋ ๊ด๋ฆฌํ์ง๋ง, ์๋ ๊ด๋ฆฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ DataSourceUtils๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
6๏ธโฃ ๊ฒฐ๋ก
Spring JDBC์ JdbcTemplate์ ๊ฐ๋จํ๊ณ ํจ์จ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ๊ฐ๋ฅํ๊ฒ ํ๋ค. ๊ธฐ์กด JDBC API์ ๋ณต์ก์ฑ๊ณผ ๋ฐ๋ณต์ฑ์ ์ ๊ฑฐํ๊ณ , ์์ธ ์ฒ๋ฆฌ์ ํธ๋์ญ์ ๊ด๋ฆฌ๋ฅผ ํตํฉํ์ฌ ์์ฐ์ฑ์ ๋์ธ๋ค.
JdbcTemplate์ ๋ ๋์๊ฐ Spring Data JPA ๋ฐ ORM ๊ธฐ์ ๋ก ํ์ฅ ๊ฐ๋ฅํ ๊ธฐ์ด๋ฅผ ์ ๊ณตํ๋ค.๐ฏ
๋ค์ ํฌ์คํ ์ ์ด์ด์ ์ค์ต์ฝ๋๋ฅผ ํ์ฉ(PlatformTransactionManager ์ฌ์ฉ)ํ์ฌ Spring Transaction์ ๋ํด ์ข ๋ ๊น๊ฒ ๋ค์ด๊ฐ๋ณผ๊น ํ๋ค.
โน๏ธ ์ฐธ๊ณ
[ASAC 6๊ธฐ ๊ฐ์์๋ฃ]
https://jiwondev.tistory.com/154
@Transactional ์ ๋์์๋ฆฌ, ํธ๋์ญ์ ๋งค๋์
๐ญ JDBC์์ ์ฌ์ฉํ๋ ํธ๋์ญ์ ์๋ฐ์ JDBC์์ ๊ฐ๋ฐ์๊ฐ ์ง์ ํธ๋์ญ์ ์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ํ๊ฐ์ง ๋ฐ์ ์์ต๋๋ค. // ์ปค๋ฅ์ ํ์์ DB์ปค๋ฅ์ ์ ๋ฐ์์๋ค๊ณ ๊ฐ์ Connection connection = dataSource.getConn
jiwondev.tistory.com
'๐ปDEV-STUDY > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring Boot, DB] DB์ Spring Boot ์ฐ๋ (1) | 2024.11.29 |
---|---|
[Spring] ์ค๋ฌด์์์ Best Practices #2 (0) | 2024.10.07 |
[Spring] ์ค๋ฌด์์์ Best Practices #1 (0) | 2024.10.07 |
[Spring] Spring Boot ์ฅ์ ๋ฐ ๋์ (0) | 2024.10.06 |
[Spring] Spring ์์ฒญ๊ฐ ์ฒ๋ฆฌ ๋ฐฉ์ (0) | 2024.10.06 |
JDBC API๋ฅผ ๊ฐํธํ๊ฒ โ JDBC Template

๐ Spring JDBC : ๊ฐํธํ JDBC API ์ฌ์ฉ์ ์ํ JDBC Template ์ ๊ณต
Spring JDBC๋ ๋ฐ๋ณต์ ์ธ JDBC API ์ฝ๋๋ฅผ ๊ฐ์ํํ์ฌ ํจ์จ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ์ง์ํ๋ค.
JDBC API๋ฅผ ์ฌ์ฉํ ๋ ๋ฐ์ํ๋ ๊ตฌ์กฐ์ ๋ฐ๋ณต ๋ฌธ์ ์ ์์ธ ์ฒ๋ฆฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Spring์ด JdbcTemplate์ ์ ๊ณตํ๋ค.


1๏ธโฃ Spring JDBC๊ฐ ํด๊ฒฐํ๋ ๋ฌธ์
1-1. ๋ฐ๋ณต๋๋ ์ฝ๋ ์ ๊ฑฐ
JDBC API๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฐ๋ณต ์์ ์ด ๋ฐ์ํ๋ค.
- Connection ๊ฐ์ฒด ์์ฑ ๋ฐ ๋ฐํ
- Statement ์์ฑ ๋ฐ ์คํ
- ResultSet ์ฒ๋ฆฌ
- ์์ธ์ฒ๋ฆฌ์ ์์ ์ ๋ฆฌ
JdbcTemplate์ ์ด ๋ชจ๋ ๊ณผ์ ์ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ๊ฐ๋จํ๊ณ ๊น๋ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋๋ก ๋์์ค๋ค.
1-2. ์์ธ ์ฒ๋ฆฌ ๊ฐ์ํ
- JDBC API๋ SQLException๊ณผ ๊ฐ์ ์์ธ๋ฅผ try-catch-finally ๋ธ๋ก์ผ๋ก ์ฒ๋ฆฌํด์ผ ํ๋ค.
- JdbcTemplate์ ์์ธ๋ฅผ Spring์ DataAccessException์ผ๋ก ๋ณํํ์ฌ ์ฒ๋ฆฌ ๊ณผ์ ์ ๋จ์ํ์ํจ๋ค.
1-3. ๊ฐ๋จํ ํธ๋์ญ์ ์ฒ๋ฆฌ
- JDBC API์์ ๋ค์์ ์ฟผ๋ฆฌ๋ฅผ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ๋ฌถ์ผ๋ ค๋ฉด ์๋์ผ๋ก Connection ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌํด์ผ ํ๋ค.
- Spring์์๋ ํธ๋์ญ์ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํด ๊ฐํธํ๊ฒ ํธ๋์ญ์ ์ ๊ด๋ฆฌํ๋ค.
2๏ธโฃ Spring JDBC: JdbcTemplate
๊ธฐ์กด์ ์ฝ๋์ธ JDBC API(https://1000sang-dev.tistory.com/79)๋ฅผ JdbcTemplate์ผ๋ก Repository ๊ตฌํ.
โป Service ๋ก์ง๋ JdbcTemplate์ ๋ง๊ฒ ์์ ํด ์ค๋ค. (์ฝ๋๋ ๋ฐ๋ก ์์ฌ๋ฆผ)
2-1. JdbcTemplate์ผ๋ก ๋จ์ผ SELECT ์ํ
JdbcTemplate๋ JDBC API์ ์ฃผ์ ๊ตฌ์ฑ ์์๋ฅผ ๊ฐ์ํํ์ฌ ์ ๊ณตํ๋ค.
@Repository
@RequiredArgsConstructor
public class UserJdbcTemplateDao {
private final JdbcTemplate jdbcTemplate;
public User findById(int userId) {
String getUserQuery = "SELECT * FROM \"user\" WHERE id = ?";
int getUserParams = userId;
return this.jdbcTemplate.queryForObject(
getUserQuery,
(resultSet, rowNum) -> new User(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getInt("age"),
resultSet.getString("job"),
resultSet.getString("specialty"),
resultSet.getTimestamp("created_at")
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
),
getUserParams
);
}
}
- queryForObject ๋ฉ์๋
- SQL ์ฟผ๋ฆฌ
- RowMapper: ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ ๋๋ค ํจ์ (ํน์ RowMapper ๊ตฌํ์ฒด)
- ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ
2-2. JdbcTemplate์ผ๋ก ๋ค์ SELECT ์ํ
@Repository
@RequiredArgsConstructor
public class UserJdbcTemplateDao {
private final JdbcTemplate jdbcTemplate;
public List<User> findAll() {
String getUserQuery = "SELECT * FROM \"user\"";
return this.jdbcTemplate.queryForStream(
getUserQuery,
(resultSet, rowNum) -> new User(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getInt("age"),
resultSet.getString("job"),
resultSet.getString("specialty"),
resultSet.getTimestamp("created_at")
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
)
).toList();
}
}
- queryForStream
- SQL ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ Java 8+์ Stream ํํ๋ก ๋ฐํํด์ค๋ค.
2-3. JdbcTemplate์ผ๋ก INSERT ์ํ
public User save(String name, Integer age, String job, String specialty) {
// (A) INSERT USER
String createUserQuery = "INSERT INTO \"user\" (name, age, job, specialty, created_at) VALUES (?, ?, ?, ?, ?)";
Object createUserParams = new Object[]{
name,
age,
job,
specialty,
LocalDateTime.now()
};
this.jdbcTemplate.update(
createUserQuery,
createUserParams,
int.class
);
// (B) SELECT id - MySQL:last_insert_id()->id / PostgresQL:currval()->lastval/lastval()->lastval
String lastInsertIdQuery = "SELECT lastval()";
int createdUserId = this.jdbcTemplate.queryForObject(
lastInsertIdQuery,
int.class
);
// (C) SELECT USER
String getUserQuery = "SELECT * FROM \"user\" WHERE id = ?";
int getUserParams = createdUserId;
return this.jdbcTemplate.queryForObject(
getUserQuery,
(resultSet, rowNum) -> new User(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getInt("age"),
resultSet.getString("job"),
resultSet.getString("specialty"),
resultSet.getTimestamp("created_at")
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
),
getUserParams
);
}
- update
- ๋จ์ผ ๋ฐ์ดํฐ ์ฝ์ ๋ฐ ์กฐ์
2-4. JdbcTemplate์ผ๋ก UPDATE ์ํ
public User update(int id, String name, Integer age, String job, String specialty) {
// (A) UPDATE USER
String updateUserQuery = "UPDATE \"user\" SET name = ?, age = ?, job = ?, specialty = ? WHERE id = ?";
Object[] updateUserParams = new Object[]{
name,
age,
specialty,
id,
};
int rowsAffected = this.jdbcTemplate.update(
updateUserQuery,
updateUserParams
);
// (B) SELECT USER
String getUserQuery = "SELECT * FROM \"user\" WHERE id = ?";
int getUserParams = id;
return this.jdbcTemplate.queryForObject(
getUserQuery,
(resultSet, rowNum) -> new User(
resultSet.getInt("id"),
resultSet.getString("name"),
resultSet.getInt("age"),
resultSet.getString("job"),
resultSet.getString("specialty"),
resultSet.getTimestamp("created_at")
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
),
getUserParams
);
}
}
2-5. JdbcTemplate์ผ๋ก DELETE ์ํ
public void delete(int userId) {
String deleteUserQuery = "DELETE FROM \"user\" WHERE id = ?";
Object[] deleteUserParams = new Object[]{
userId
};
this.jdbcTemplate.update(
deleteUserQuery,
deleteUserParams
);
}
3๏ธโฃ JdbcTemplate ์ฅ์
1. ์ฝ๋ ๊ฐ์ํ
- ๋ณต์กํ JDBC API ์ฝ๋๋ฅผ ์ ๊ฑฐํ์ฌ ๊ฐ๊ฒฐํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ฝ๋ ์์ฑ ๊ฐ๋ฅ.
2. ์์ธ ์ฒ๋ฆฌ ํต์ผ
- Spring์ DataAccessException์ผ๋ก ์์ธ๋ฅผ ํตํฉ ๊ด๋ฆฌ.
3. ํธ๋์ญ์ ๊ด๋ฆฌ ํตํฉ
- Spring์ ํธ๋์ญ์ ๊ด๋ฆฌ์๋ฅผ ํ์ฉํด ์์ฝ๊ฒ ํธ๋์ญ์ ์ฒ๋ฆฌ ๊ฐ๋ฅ.
4. ๋ฐ๋ณต ์์ ์ ๊ฑฐ
- Connection ์์ฑ, ์์ ๋ฐํ, SQLException ์ฒ๋ฆฌ ๋ฑ ๋ฐ๋ณต ์์ ์ด ํ์ ์์.
4๏ธโฃ ํธ๋์ญ์ ์ฒ๋ฆฌ
Spring์์๋ PlatformTransactionManager์ @Transactional์ ์ฌ์ฉํ์ฌ ํธ๋์ญ์ ์ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค
ํธ๋์ญ์ ์ฃผ์ ๊ฐ๋
- ํธ๋์ญ์ ์์ฑ: Connection ์์ฑ
- ํธ๋์ญ์ ์ฐธ์ฌ: ๋์ผ Connection์์ ์์ ์ํ
- ํธ๋์ญ์ ์ฒ๋ฆฌ: ์ ์ ์ข ๋ฃ ์ Commit, ์์ธ ๋ฐ์ ์ RollBack

5๏ธโฃ JdbcTemplate ์ฌ์ฉ ์ ์ฃผ์ ์ฌํญ
1. DataSource ์ค์
- JdbcTemplate๋ ๋ด๋ถ์ ์ผ๋ก DataSource๋ฅผ ์ฌ์ฉํ๋ฏ๋ก, ์ ์ ํ ์ค์ ๋ DataSource๊ฐ ํ์ํ๋ค.
2. ํธ๋์ญ์ ์ปจํ ์คํธ
- @Transactional ์ฌ์ฉ ์ ๋ชจ๋ ์ฟผ๋ฆฌ๊ฐ ๋์ผ Connection์์ ์คํ๋๋๋ก ๋ณด์ฅ๋๋ค.
3. Connection ๊ด๋ฆฌ
- Spring์ Connection์ ์๋ ๊ด๋ฆฌํ์ง๋ง, ์๋ ๊ด๋ฆฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ DataSourceUtils๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
6๏ธโฃ ๊ฒฐ๋ก
Spring JDBC์ JdbcTemplate์ ๊ฐ๋จํ๊ณ ํจ์จ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ๊ฐ๋ฅํ๊ฒ ํ๋ค. ๊ธฐ์กด JDBC API์ ๋ณต์ก์ฑ๊ณผ ๋ฐ๋ณต์ฑ์ ์ ๊ฑฐํ๊ณ , ์์ธ ์ฒ๋ฆฌ์ ํธ๋์ญ์ ๊ด๋ฆฌ๋ฅผ ํตํฉํ์ฌ ์์ฐ์ฑ์ ๋์ธ๋ค.
JdbcTemplate์ ๋ ๋์๊ฐ Spring Data JPA ๋ฐ ORM ๊ธฐ์ ๋ก ํ์ฅ ๊ฐ๋ฅํ ๊ธฐ์ด๋ฅผ ์ ๊ณตํ๋ค.๐ฏ
๋ค์ ํฌ์คํ ์ ์ด์ด์ ์ค์ต์ฝ๋๋ฅผ ํ์ฉ(PlatformTransactionManager ์ฌ์ฉ)ํ์ฌ Spring Transaction์ ๋ํด ์ข ๋ ๊น๊ฒ ๋ค์ด๊ฐ๋ณผ๊น ํ๋ค.
โน๏ธ ์ฐธ๊ณ
[ASAC 6๊ธฐ ๊ฐ์์๋ฃ]
https://jiwondev.tistory.com/154
@Transactional ์ ๋์์๋ฆฌ, ํธ๋์ญ์ ๋งค๋์
๐ญ JDBC์์ ์ฌ์ฉํ๋ ํธ๋์ญ์ ์๋ฐ์ JDBC์์ ๊ฐ๋ฐ์๊ฐ ์ง์ ํธ๋์ญ์ ์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ํ๊ฐ์ง ๋ฐ์ ์์ต๋๋ค. // ์ปค๋ฅ์ ํ์์ DB์ปค๋ฅ์ ์ ๋ฐ์์๋ค๊ณ ๊ฐ์ Connection connection = dataSource.getConn
jiwondev.tistory.com
'๐ปDEV-STUDY > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring Boot, DB] DB์ Spring Boot ์ฐ๋ (1) | 2024.11.29 |
---|---|
[Spring] ์ค๋ฌด์์์ Best Practices #2 (0) | 2024.10.07 |
[Spring] ์ค๋ฌด์์์ Best Practices #1 (0) | 2024.10.07 |
[Spring] Spring Boot ์ฅ์ ๋ฐ ๋์ (0) | 2024.10.06 |
[Spring] Spring ์์ฒญ๊ฐ ์ฒ๋ฆฌ ๋ฐฉ์ (0) | 2024.10.06 |