본문 바로가기
👨‍💻 프로그래밍/Spring Data, JPA, DB

JDBC, 필요한 만큼만 알아보기

by 개발자 진개미 2024. 5. 5.
반응형

JDBC, 뭐 하는 거야?

JDBC (Java Database Connectivity)는 Java에서 DB에 연결하기 위한 API입니다. 

조금이라도 복잡하고 유용한 Application을 만들려면 DB에 연결하는게 필수인데 이를 위해서는 크게 다음과 같은 과정을 따릅니다.

  1. DB와 연결 (TCP/IP를 맺고, 암호화 정보 전달하고 등)
  2. SQL문 전달
  3. (필요하다면) Transaction 처리
  4. 결과를 받아서 처리

 

문제는 이 과정이 DB 마다 모두 조금씩 다르다는 겁니다... 새로운 DB를 쓸 때 마다 각 DB의 특성을 공부해서 이 과정을 진행해야 한다면 지옥이 따로 없겠죠? 그렇기 때문에 JDBC라는 표준 API를 제공하고, 각 DB가 이 JDBC를 구현해서 개발자는 JDBC의 사용법만 알면 Application에서 쉽게 DB를 사용할 수 있게 됐습니다!


SQL Mapper, ORM (JPA)도 모두 사실은 JDBC를 쓴다

저는 JDBC를 처음 국비지원학원에서 접하고 써 봤는데요. 그 이후로는 단 1번도 JDBC를 쓴 적이 없습니다. JDBC가 나올 당시에는 혁신적이였지만 지금은 직접 쓰지는 않는 기술입니다. 반복되는 코드가 너무 많고, 직접 Connection을 관리해야 하는 등의 불편한 점이 있기 때문입니다. 하지만 직접 JDBC를 쓰지 않을 뿐 많이 쓰는 SQL MapperORM이 사실은 JDBC를 추상화 한 것입니다.

 

SQL Mapper?

직접 JDBC를 사용하지 않고, SQL만 직접 작성하면 DB와 관련된 여러 작업을 자동으로 처리해 줍니다. MyBatis나 JdbcTemplate이 SQL Mapper의 예시입니다. 

ORM?

보통 SQL을 직접 작성하지 않고 DB Entity와 객체를 자동으로 변환시켜 주고, 여러 기본적인 SQL도 자동으로 생성해 줘서 DB를 쓰지만 DB가 아닌 객체를 다루는 것 같은 경험을 줍니다.


JDBC 핵심 아키텍처

JDBC에서 알아야 할 구성 요소는 아래 4가지가 전부입니다!

  • Connection (DataSource)
  • Statement
  • ResultSet
  • Driver

 

Connection (DataSource)

ConnectionDB와의 연결을 나타내는 객체입니다. DB와 연결하기 위해서는 여러 과정을 거쳐야 하는데 이 과정이 너무 복잡하고 DB마다 다르기 때문에 Connection 객체로 추상화를 진행했습니다. DataSource는 여기에 나아가서 Connection을 얻는 방법까지 추상화를 한 겁니다. Connection은 요청할 때 마다 얻고 다 쓰면 끊을 수도 있지만 이렇게 하면 비용이 너무 많이 들기 때문에 Connection Pool이라는 걸 만들어서 Connection을 미리 여러개 맺어 놓고 필요할 때 갖다 쓰고 다 써도 끊지 않고 다시 반환합니다. 하지만 Connection Pool도 여러 방식이 있을 수 있기 때문에 이런 Connection을 얻는 방식 자체를 추상화한게 DataSource입니다. 


 

Statement

SQL문 1개를 나타냅니다. Statement의 method를 통해 SQL을 실행할 수 있습니다. 보통은 PreparedStatement를 사용하는데, Statement에서 Parameter Binding이라는 기능을 추가해 SQL Injection 공격을 막을 수 있기 때문에 거의 필수로 사용해야 합니다!

String sql = "select * from member where member_id = ?";
pstmt = connection.prepareStatement(sql);
pstmt.setString(1, memberId);

위와 같이 SQL문에 직접 데이터를 넣지 않고 ?로 대체한 후, PreparedStatement의 .setString 등의 method를 사용해서 데이터를 넣습니다. 이렇게 하면 유저가 SQL Injection이라 불리는 공격을 막을 수 있습니다.

위의 예시에서는 만약에 유저가 member_id1이 아닌 1 OR 1=1;을 넣었다고 가정하면 SQL문은 아래와 같이 됩니다.

select * from member where member_id = 1 OR 1=1;

이 경우 where 절이 항상 true이기 때문에 모든 회원의 데이터가 응답으로 갈 수 있습니다... 하지만 PreparedStatement의 Data Binding을 쓰면 1 OR 1=1;이 단순 String으로 취급되기 때문에 그럴 일이 없습니다.


 

ResultSet

Connection 객체를 얻어서 Statement를 전달한 뒤 실행하면 결과를 받아야 합니다. 이 결과가 ResultSet으로 옵니다! 아래와 같이 .next()를 호출하면 next에 데이터가 있으면 true, 없으면 false를 반환하고 .getString 등을 사용해 데이터를 가져올 수 있습니다.

resultSet = pstmt.executeQuery();
while (resultSet.next()) {
	resultSet.getString("member_id");
}

 

Driver

Driver는 각 DB에 맞게 JDBC를 구현한 구현체입니다. 예를 들어 MySQL JDBC Driver는 MySQL과 연결할 수 있게 JDBC를 구현한거고, Oracle JDBC Driver는 Oracle DB와 연결할 수 있게 JDBC를 구현한 겁니다.


java.sql package가 사실은 JDBC!

java.sql의 핵심 요소?

java.sql에는 JDBC의 핵심 요소인 Connection, Statement, ResultSet, DriverManager, SQLException 등이 포함돼 있습니다. 

 

javax.sql은 뭐야?

javax.sql은 JDBC의 기본 기능에 더해 자주 쓰는 DB 관련 기능이 포함 돼 있습니다. DataSourcePreparedStatement도 javax.sql에 있습니다!


반응형