JDBC란
JDBC란
JDBC(Java DataBase Connectivity)는 자바 프로그램에서 Database를 조작하게 해주는 API이다. JDBC API는 JDK에서 제공하며 JDBC 프로그래밍을 위해서는 JDBC드라이버가 필요하다. JDBC 드라이버는 각 DBMS 회사에서 제공하는 라이브러리 압축파일이다. 이번 체스 미션에서는 MySQL을 사용하기 때문에, MySQL 드라이버를 사용했다.
JDBD API 클래스
JDBC 클래스와 인터페이스는 자바 패키지 java.sql과 javax.sql에 포함되어 있다.
JDBC를 이용한 데이터베이스 연동과정
JDBC 드라이버 로드
Class.forName("com.mysql.cj.jdbc.Driver");
Class.forName("com.mysql.cj.jdbc.Driver")
를 호출하여, mysql에서 제공하는 Driver 클래스를 JVM method area에 로딩시킨다.
데이터베이스 연결
private static final String URL = "jdbc:mysql://localhost:3307/chess";
private static final String USER = "user";
private static final String PASSWORD = "password";
Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
URL에는 MySQL의 포트번호와 데이터베이스 이름을 지정해주면 된다. 로컬 환경에서 MySQL의 포트번호는 3306이다. 체스 미션에서는 docker 환경에서 MySQL 을 사용했기 때문에, 포트를 3307로 지정해주었다. (저는 기존에 따로, 로컬 환경에서 3306 포트를 사용하고 있었습니다.)
이제 Connection 객체를 만들어 사용하게 되는데, DriverManager의 getConnection() 을 호출해서, MySQL에 연결하기 위한 커넥션 정보를 입력한다. Connection 객체가 만들어지면, Query 문을 실행시키는 statement 객체를 생성할 수 있다.
Query 실행을 위한 객체 생성
- Statement
String sql = "insert into board (position, piece, color, game_id) values ('" + position +", " + piece + ", " + color +", " + game_id + "')";
Statement statement = connection.createStatement();
statement.executeQuery(sql);
- PreparedStatement (Statement 를 상속한 인터페이스)
final String sql = "insert into board (position, piece, color, game_id) values (?, ?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql));
statement.setString(1, position);
statement.setString(2, piece);
statement.setString(3, color);
statement.setInt(4, id);
statement.executeUpdate();
SQL 서버 엔진이 쿼리를 수행할 때 다음 과정을 거친다.
- 구문 분석 및 정규화 단계 : 쿼리 문법 및 테이블과 칼럼이 존재 여부를 확인한다.
- 컴파일 단계 : 쿼리를 컴파일한다.
- 쿼리 최적화 계획 : 쿼리를 실행할 수 있는 방법의 수와 비용을 알아내 최적의 계획을 선택한다.
- 캐시 : 선택된 계획은 캐시에 저장되고 동일한 쿼리가 들어올때마다 Cache 찾아 실행한다. (1, 2, 3 단계는 실행되지 않는다.)
- 실행 단계 : 쿼리가 실행되고 데이터가 ResultSet 객체로 사용자에게 반환된다.
그럼 Statement와 PreparedStatement의 차이가 뭘까?
Statement와 PreparedStatement의 차이는 캐시 사용여부이다.
Statement는 쿼리를 실행할 때마다 위의 1~5 단계를 수행해야 한다.
PreparedStatement는 위의 코드를 보다 시피, 완전한 쿼리가 아니다.
쿼리의 틀을 미리 생성해 놓고 물음표를 대체할 값을 나중에 지정한다.
따라서 PreparedStatement가 처음 실행될 때만 1~3 단계를 수행 하고 캐시에 담아 재사용하게 한다.
이후에 Placeholder Replacement
라는 추가 단계가 있는데, 런타임시에 사용자가 입력한 데이터로 set메서드를 사용해 ?를 대체한다.
참고
https://velog.io/@jsj3282/Statement%EB%B3%B4%EB%8B%A4-Preparedstatement%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0%EC%84%B1%EB%8A%A5-%EB%B3%B4%EC%95%88-%EC%B8%A1%EB%A9%B4