JDBC
JDBC에 대해서 적어봤습니다.
주제 선정 이유
백엔드를 공부하다 보면 자연스럽게 데이터베이스를 다루게 되며, JPA나 MyBatis 같은 영속성 프레임워크를 사용하면서 이렇게 쓰면 되는구나 하고 넘어가게 되기도 하지만 학습이 깊어질수록 이 프레임워크들은 내부에서 어떻게 DB와
통신하는지 궁금증이 생기기도 하고, 그 과정에서 자바와 데이터베이스를 연결하는 가장 기본적인 기술인
JDBC(Java Database Connectivity)를 알게 되기도 합니다.
또한 단순히 프레임워크를 사용하는 것을 넘어 실제로 데이터가 어떤 과정을 거쳐 전달되고 처리되는지 이해해보고
싶다는 생각이 들게 되며, JDBC와 영속성 프레임워크가 어떤 관계를 가지고 있는지에 대해서도 함께 정리해볼 필요성을 느끼게 됩니다.
그래서 이번 글에서는 JDBC를 중심으로 데이터 접근 방식이 어떻게 발전해왔는지 살펴보면서, 영속성 프레임워크가
이를 어떻게 추상화하고 발전시켰는지에 대해 정리해보고자 합니다.
JDBC가 뭘까?
자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API인데 데이터베이스에서 자료를 쿼리하거나 업데이트 하는
방법을 제공하며 대표적으로 다음 3가지 기능을 표준 인터페이스로 정의해서 제공합니다.
java.sql.Connection- 연결java.sql.Statement- SQL을 담은 내용java.sql.ResultSet- SQL 요청 응답
이 JDBC 인터페이스를 각각의 DB 벤더에서 자신의 DB에 맞도록 구현해서 라이브러리로 제공하는데 이것을 JDBC
드라이버라고 합니다.
MySQL DB에 접근할 수 있는 것은MySQL JDBC드라이버라 하고,
Oracle DB에 접근할 수 있는 것은Oracle JDBC드라이버라 한다.
JDBC 동작 흐름
애플리케이션은 직접 데이터베이스와 통신하지 않고, JDBC API를 통해 요청을 전달하는데 이 요청은 각 데이터베이스 벤더에서 제공하는 JDBC 드라이버로 전달되며, 드라이버가 실제 데이터베이스와의 연결, SQL 전송, 결과 수신을
담당하게 되고 이 구조 덕분에 개발자는 종류에 상관없이 표준화된 JDBC API만 사용하면 됩니다.
JDBC API 사용 흐름
JDBC 드라이버를 로딩한 후 데이터베이스와의 연결을 담당하는 Connection 객체를 생성하고 이후에 SQL을 실행하기 위한 Statement 객체를 생성하고 쿼리를 실행하면, 그 결과는 ResultSet 객체를 통해 조회할 수 있습니다.
모든 작업이 끝난 후 ResultSet, Statement, Connection을 순서대로 종료하여 사용한 자원을 해제해야 합니다.
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import lombok.Data;
@Data
public class Member {
private String memberId;
private int money;
public Member() {
}
public Member(String memberId, int money) {
this.memberId = memberId;
this.money = money;
}
}
회원의 ID와 해당 회원이 소지한 금액을 표현하는 단순한 클래스를 Member라는 테이블에 데이터를 저장하고
조회할 때 사용하겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import hello.jdbc.connection.DBConnectionUtil;
import hello.jdbc.domain.Member;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class MemberRepositoryExample {
public void save(Member member) throws SQLException {
String sql = "INSERT INTO member(member_id, money) VALUES (?, ?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DBConnectionUtil.getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
pstmt.executeUpdate();
} finally {
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
}
}
}
이런식으로 JDBC API를 사용하여 데이터를 저장하면 되는데 방법은 다음과 같습니다.
DBConnectionUtil.getConnection()을 통해 데이터베이스와의 연결을 담당하는Connection객체를 생성합니다.Connection객체를 사용해 SQL을 실행할 수 있는PreparedStatement객체를 생성합니다.setString(),setInt()메서드를 통해 SQL의 파라미터 값을 설정한 후executeUpdate()를 호출하여
INSERT쿼리를 실행합니다.PreparedStatement와Connection을close해서 접속을 종료합니다.
한계
반복적인 보일러플레이트 코드로 인해 가독성과 생산성이 떨어지지만 자원 생성과 해제를 개발자가 직접 처리해야 하며 try-catch-finally 구조까지 함께 사용해야 하는 번거로움이 존재했습니다.
또한 SQL이 자바 코드 내부에 직접 작성되어 변경 시 코드 수정이 불가피해 유지보수가 어려워지며 애플리케이션과
데이터 접근 로직 간의 결합도가 높아지는 문제가 발생하고 여러 쿼리를 하나의 작업 단위로 처리하기 위해 commit, rollback을 직접 제어해야 하며 로직이 복잡해질수록 트랜잭션 관리 또한 함께 어려워지는 한계가 존재했습니다.
SQL Mapper와 ORM
위와같은 문제점들을 해결하기 위해 JDBC 위에서 동작하는 추상화 기술 SQL Mapper, ORM이 등장하게 되었습니다.
SQL Mapper
SQL을 직접 작성하되, JDBC에서 반복되던 커넥션 관리, 자원 해제, 예외 처리 등의 작업을 프레임워크가 대신
처리해주는 방식입니다.
- 장점
JDBC를 편리하게 사용하도록 도와준다.
- 대표기술
- 스프링
JdbcTemplate,MyBatis
- 스프링
ORM
ORM(Object-Relational Mapping)은 객체와 관계형 데이터베이스 테이블을 매핑하여 데이터를 객체 중심으로 다룰 수 있도록 도와주는 기술이며 반복적인 SQL을 직접 작성하지 않고 ORM 프레임워크가 내부적으로 SQL을 생성하여
실행합니다.
- 장점
SQL쿼리 작성 없이 객체 중심으로 DB를 다룰 수 있어 개발 생산성이 높다.
- 대표기술
JPA,Hibernate
그래서 어떻게 쓰라고?
결국 어떤 기술이 더 좋다고 단정 지을 수 있는 것은 아니며 프로젝트의 성격과 요구사항에 따라 선택이 달라지게 되고,
각 방식이 가지는 특징과 장단점을 이해한 뒤 상황에 맞게 사용하는 것이 중요하며 이를 정리해보면 다음과 같습니다.
| 구분 | 설명 |
|---|---|
| SQL Mapper | 단순한 쿼리 위주의 프로젝트이거나 SQL을 직접 제어해야 하며 복잡한 쿼리 튜닝이 중요한 경우 적합 |
| ORM | 도메인 중심 설계가 중요하고 CRUD 위주의 비즈니스 로직이 많은 경우 개발 생산성 측면에서 유리 |
마무리
JDBC와 영속성 프레임워크의 등장 배경을 살펴보며 핵심을 다시 정리해보면 다음과 같습니다.
JPA나MyBatis같은 영속성 프레임워크를 사용하더라도, 내부적으로는 결국JDBC를 통해 데이터베이스와
통신합니다.JDBC는 자바와 데이터베이스를 연결하는 가장 근본적인 기술이지만, 반복적인 코드와 복잡한 자원·트랜잭션
관리로 인해 실무에서 직접 사용하기에는 부담이 큽니다.이러한
JDBC의 한계를 해결하기 위해SQL Mapper와ORM같은 영속성 프레임워크가 등장했으며, 개발자는
비즈니스 로직에 더 집중할 수 있게 되었습니다.결국 영속성 프레임워크는
JDBC를 대체하는 기술이 아니라,JDBC를 더 편리하고 안전하게 사용할 수 있도록
추상화한 도구라고 볼 수 있습니다.






