Topic = JCDB의 구성요소 및 주 기능 이해하기
JDBC - Java Database Connectivity
JDBC란?
- Java 애플리케이션이 데이터베이스와 연결하고, SQL 쿼리를 실행할 수 있도록 해주는 API 이다. 이를 위해 필요한 클래스와 인터페이스 들이 여러가지 있는데, 대표적으로 java.sql 패키지가 있다.
JDBC 주요 구성요소
- Connection
데이터베이스와의 연결을 나타내는 객체를 추상화한 인터페이스로 데이터베이스와의 세션을 관리하고 SQL 쿼리를 실행하기 위한 Statement 객체를 생성하는 데 사용된다.
✅ 자바 애플리케이션에서 Connection 객체를 사용하기 위해서는 java.sql 패키지의 Connection 을 사용하게 된다. 해당 Connection 은, 다양한 데이터베이스의 Conneciton ( MySQL Connection, Oracle Connection 등... ) 으로 나누어진 여러 DB의 Connection을 추상화한 인터페이스이다. 때문에 특정 데이터베이스의 세부사항에 신경쓰지 않고 DB와 상호작용 할 수 있게된다.
📚h2\driver.class [ h2db ], jdbc\dirver.class [ mariadb ] 등 경로에서 database driver 패키지에 java.sql ( JDBC )의 Connection 추상화 객체를 구체화하고 있는 것을 확인할 수 있다. - Statement ( PreparedStatement )
SQL 쿼리를 데이터베이스에 전송하고 결과를 반환받기 위한 객체를 추상화한 인터페이스로 SQL 쿼리를 실행할 때 사용된다.
✅ 쿼리를 실행하기 위한 메서드를 제공한다. 이 메서드들도 Connection과 마찬가지로 JDBC에서 지원하는 다양한 데이터 베이스에 동일한 결과를 얻을 수 있도록 설계되었다.
[ JDBC - Statement 쿼리 실행 메서드 ]
- execute() : Boolean ➡️ DB의 리턴 값이 ResultSet일 경우에 true, ResultSet이 아닐 경우 false를 반환한다.
- executeQuery() : ResultSet ➡️ 쿼리 검색 결과를 포함한 ResultSet객체를 반환한다.
- executeUpdate() : Int ➡️업데이트가 반영된 요소의 갯수를 반환한다. - ResultSet
SQL 쿼리 실행 결과를 나타내는 객체를 추상화한 인터페이스로 해당 인터페이스를 구현한 객체는, 쿼리에서 반환된 데이터에 접근하고 이를 순회할 수 있는 방법을 제공한다.
✅ 행 및 열 탐색으로 반환 결과 집합의 각 행을 순회할 수 있으며, next() 메서드를 호출하여 결과 테이블의 행을 가르키는 포인터를 다음 행으로 이동한다. 기본적으로 포인터는 결과 집합의 첫번째 행 전에 위치한다.
[ JDBC - ResultSet 사용 예 ]
- while( rs.next() ) { } ➡️ ResultSet의 포인터가 next() 를 통해 다음행으로 이동이 가능할 때 true를 반환하며 포인터가 이동된다.
- rs.getType("columnName") ➡️포인터가 위치한 행의 columnName에 해당하는 Type 타입의 값을 반환한다. - JDBC DriverManager
데이터베이스 연결을 관리하는 클래스로, 데이터베이스에 연결하기 위한 메서드를 제공한다.
✅앞서 Connection 에서 설명한대로, 동일한 Connection 인터페이스를 사용하더라도, 각 데이터베이스의 특성에 맞춘 구현체가 존재한다. JDBC DriverManager는 이러한 Connection 들을 mysql.cj.jdbc.Driver 클래스를 사용하여 MySQL 데이터 베이스에 연결하는 등 각 데이터베이스에 맞는 방식으로 연결을 처리한다.
JDBC 작동원리
- 커넥션 조회
애플리케이션 로직 또는 Connection Pool 에서 Connection을 얻기 위해 JDBC Driver에 연결 정보를 전달한다.
- DriverManager.getConnection(url, username, password ) 메서드 호출이 이단계에 해당한다. - JDBC DriverManager
연결 정보 ( URL, driver-class-name ) 등의 형식에 일치하는 데이터베이스 Driver를 로드하여 데이터베이스와의 연결을 가능하게 한다. - Connection 응답 결과 반환, Connection 객체 생성
DB와 연결을 마치면, 반환 받은 응답 결과를 토대로 JDBC의 Connection 인터페이스를 구현하는 Connection 객체를 반환한다. - 쿼리 실행, 결과 처리
쿼리 실행시 사용되는 Statement 또는 PreparedStatement 객체를 생성하여 execute() 등의 쿼리 실행 메서드를 통해 결과를 ResultSet 객체로 받아온다.
🚨Statement, PreparedStatement ?
- Statement
- Statement는 정적으로 쿼리를 실행하는 인터페이스이다. 보안과 성능 문제로 사용되지 않는다.
- 객체 생성 및 쿼리 실행
Connection.createStatement() 메서드를 통해 객체를 생성한다.
Statement.executeQuery("SQL id = ${사용자 입력 값}") 와 같이 정적인 쿼리를 실행하게되는데 이는 사용자 입력 값을 직접 쿼리에 포함시키기 때문에 SQL 인젝션 공격에 취약하며, 쿼리가 DB에 전송될 때마다 파싱되고 컴파일 되므로 성능이 떨어진다. - PreparedStatement
- PreparedStatement 인터페이스는 SQL 쿼리를 미리 컴파일하고, 실행 시에 파라미터를 바인딩하여 사용하는 동적으로 쿼리를 실행하게 된다.
- 객체 생성 및 쿼리 실행
Connection.prepareStatement("SQL id = ?") 메서드를 통해 객체 생성 시 SQL 쿼리를 미리 지정해두게 되고 변동 가능한 부분을 ' ? ' 파라미터로 받게 된다.
pstmt.setInt(1, userId) 메서드를 통해 쿼리 실행 시 1번째 ? 파라미터에 userId를 동적으로 바인딩하여 실행되게 된다.
[ A. 오늘 복습한 내용 / B. 다음에 학습할 내용 ]
A. Connection, JDBC
B. DB Transaction
B. SQL Mapper - JDBC Template, MyBatis
[오류,에러 등등]
1. Hikari Connection Pool에서 Connection 객체를 생성하는 방법을 이해해보려다 실패.
- 한번쯤은 봐두는 게 좋을 것 같아 시간이 여유로울 때 CP 다시 한번 파보기.
[Comment]
1.
[Reference]
[ JDBC - State - Query 실행 메서드 ]
[ JDBC ]