스프링으로 백엔드 개발을 하다 보면,
데이터베이스랑 연결하고 데이터를 가져오거나 저장하는 일이 흔하다.
이때 사용하는 핵심 구성요소가 바로
- DataSource (데이터 소스)
- JDBC (Java Database Connectivity)
- JdbcTemplate
- RowMapper
이다.
이번 글에서는 이 구성요소들이 어떻게 연결되어 동작하는지 정리해 보았다.
데이터 소스
DataSource는 데이터베이스와 연결을 관리하는 객체이다.
스프링은 데이터 소스를 통해 커넥션을 만들고 재사용하고 닫는다.
쉽게 말하면 DB 연결을 대신 관리해주는 도우미이다.
DriverManager.getConnection()을 매번 호출하면 비용이 너무 크다. → DataSource는 커넥션을 미리 만들어 놓고 재활용한다.
DataSource ds = new HikariDataSource(); // 가장 많이 쓰는 data source 구현체 = HikariCP
JDBC 란?
JDBC는 자바에서 데이터베이스에 연결할 수 있게 해주는 기본 기능이다.
자바는 특정 DB에 종속적이지 않기 때문에, DB마다 다른 통신 방식을 JDBC 드라이버가 맞춰줘야 한다.
- MySQL → com.mysql.cj.jdbc.Driver
- H2 → org.h2.Driver
Connection con = DriverManager.getConnection(url, user, pw);
문제는 이렇게 직접 쓰면 매번,
커넥션 열기 / 쿼리 작성 / 파라미터 바인딩 / 예외 처리 / 결과 파싱 등을
매번 반복해야 한다는 것이다.
그래서 등장한 것이 JdbcTemplate이다.
JdbcTemplate 이란?
JdbcTemplate은 JDBC를 더 쉽게 쓰게 도와주고, 반복 작업을 간결하게 해주는 스프링 도구이다.
복잡한 코드를 줄여주고, 예외 처리, 커넥션 해제 등을 자동으로 해준다.
int rows = jdbcTemplate.update("INSERT INTO purchase VALUES (?, ?)", id, price);
- update() : INSERT, UPDATE, DELETE 쿼리 실행
- query() : SELECT 쿼리 실행 + 결과 매핑
RowMapper 란?
SELECT 쿼리를 실행하면 데이터베이스는 결과를 ResultSet형태로 반환한다.
이 데이터를 자바 객체로 변환해서 사용해야 한다.
-> 그것을 해주는게 RowMapper 이다.
1개의 row를 객체 1개로 변환하는 로직을 제공해준다.
public List<Purchase> findAllPurchases() {
String sql = "SELECT * FROM purchase"; // 구매 테이블의 모든 레코드 가져온다
RowMapper<Purchase> purchaseRowMapper = (r,i) -> { // r은 데이터베이스에서 가져온 데이터인 ResultSet 이고, i는 행번호를 나타내는 정수이다
Purchase rowObject = new Purchase(); // 결과집합의 각 행에 대해 아래 로직을 반복한다.
rowObject.setId(r.getInt("id"));
rowObject.setProduct(r.getString("product"));
rowObject.setPrice(r.getBigDecimal("price"));
return rowObject;
};
return jdbc.query(sql, purchaseRowMapper);
}
jdbc.query(sql, purchaseRowMapper);
- sql 쿼리를 실행해서 DB에서 purchase 테이블의 모든 행을 SELECT 한다.
- 각 행(row)에 대해 purchaseRowMapper가 호출된다. 즉 ResultSet에서 한 줄 읽고, Java 객체(Purchase)로 변환하는 것이다.
- 이렇게 변환된 Purchase 객체들을 List<Purchase>로 모아서 반환한다.
전체 흐름 정리
[1] JdbcTemplate → [2] DataSource → [3] DBMS
↑ ↓
[6] RowMapper ← [5] ResultSet ← [4] SQL 실행
1. JdbcTemplate이 SELECT 쿼리 실행 요청(커넥션 요청)
2. DataSource가 DB 커넥션 제공 (필요시 새로 생성)
3. 커넥션을 통해 DBMS에 쿼리 전송
4. DBMS가 결과(ResultSet) 반환
5. JdbcTemplate이 결과를 받아
6. RowMapper로 자바 객체(Purchase 등)로 변환
마무리
스프링에서 DB를 다루기 위한 최소한의 구성은 이렇다.
- DataSource가 커넥션 관리
- JdbcTemplate이 쿼리 실행
- RowMapper가 결과를 객체로 변환
이 구조만 이해하면 소규모 앱에서 ORM 없이도 충분히 DB 작업이 가능하다.
'스프링' 카테고리의 다른 글
스프링 애스펙트 (0) | 2025.04.04 |
---|---|
스프링에서 데이터베이스 다루기 2 – 사용자 정의 DataSource 설정 (0) | 2025.04.03 |
스프링에서 다른 서버 API 호출하기 (0) | 2025.04.02 |
스프링 빈의 스코프와 생명주기 (0) | 2025.04.01 |
스프링 추상화와 의존성 주입 (2) | 2025.03.31 |