Extra Knowledge
JDBC API에 대해서
Bubbles
2023. 10. 19. 19:59
✉️ JDBC 드라이버란?
- DBMS와의 통신을 담당하는 자바 클래스
- DBMS마다 별도의 JDBC 드라이버가 필요하고, 각 DBMS는 JDBC 드라이버를 jar 파일 형태로 제공한다.
- 일반적인 JDBC Url : jdbc:[DBMS]:[데이터베이스 식별자] 형태로 url 제공
- Mysql의 경우
- jdbc:mysql://HOST[:PORT]/DBNAME[?param=value¶m1=value2&...]
- Mysql의 경우
- 웹 어플리케이션 구동할 때 한 번만 로딩되도록 구현하면 된다.
- 서블릿의 init() : 서블릿 초기화할 때 최초에 한 번 실행
- 톰캣과 같은 컨테이너는 서블릿을 사용하기 전에 초기화를 수행하므로 init() 메소드에서 JDBC 드라이버를 로딩하도록 구현하면 컨테이너 실행할 때 JDBC 드라이버를 로딩할 수 있다.
✉️ JDBC 구조
자바 웹 / 어플리케이션 - JDBC API - JDBC 드라이버 - 데이터베이스
✉️ JDBC 프로그램의 실행순서
- JDBC 드라이버 로딩
- Class.forName()
- 데이터베이스 커넥션 생성
- DriverManager.getConnection( jdbcDriver , dbUser, dbPass)
- DriverManager.getConnection( String jdbcURL)
- DriverManager.getConnection( String jdbcURL, String user, String password )
- Connection 객체를 생성하지 못 할 경우 SQLException 발생시킨다.
- DriverManager.getConnection( jdbcDriver , dbUser, dbPass)
- 쿼리 실행을 위한 Statement 객체 생성
- statement = connection.createStatement()
- PreparedStatement : statement와 동일한 기능을 제공한다.
- connection.prepareStatement()
- PreparedStatement.set() 통해서 필요한 값 지정
- executeQuery / executeUpdate 통해 쿼리 실행
- finally 블록에서 사용한 preparedStatement 닫음
- Statement 쿼리 대신 PreparedStatement 쿼리를 사용하는 주된 이유가 무엇인가?
- 값 변화를 자동으로 하기 위해
- 작은 따옴표가 들어간 값을 지정하려면 작은따옴표 두 번 사용해서 감싸주지 않고, setString으로 알아서 값을 변경해줌
- TIMESTAMP, DATE, TIME 처럼 각 DBMS마다 다른 데이터들 넣을 때는 Statement로 값을 지정해서 사용하면 DBMS마다 코드 달라짐
- 간결한 코드를 위해
- 검색 조건 지정할 때 일일이 따옴표로 구분하고 +로 연결하는 것보다, ?로 표시해두고 setString으로 각각 넣어주는 것이 간결함
- 값 변화를 자동으로 하기 위해
- 쿼리 실행
- statement.executeQuery(query)
- ResultSet executeQuery(String query) : SELECT 쿼리를 실행한다.
- int executeUpdate(String query) : INSERT, UPDATE, DELETE 쿼리를 실행한다.
- statement.executeQuery(query)
- 쿼리 실행 결과 사용
- statement 종료
- 데이터베이스 커넥션 종료
Class.forName("com.mysql.jdbc.Driver");
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
String jdbcDriver = "jdbc:mysql://localhost:3306/~~";
String dbUser = "";
String dbPass = ""; // pw
String query = "select * from MEMBER order by MEMBERID";
// connection 생성
connection = DriverManager.getConnection(jdbcDriver, dbUser, dbPass);
// Statement 생성
statement = connection.createStatement();
// 쿼리 실행
resultSet = statement.executeQuery(query);
// 쿼리 실행 결과 출력
while (resultSet.next()) {
// 데이터 꺼내오기
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
// 사용한 statement 종료
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
}
}
// 커넥션 종료
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
}
}
}
✉️ JDBC Transaction
두 개 이상의 쿼리가 모두 성공적으로 실행해야 데이터가 정상적으로 처리되는 경우 DBMS는 트랜잭션을 이용하여 두 개 이상의 쿼리를 마치 한 개의 쿼리처럼 처리할 수 있도록 하고 있다.
try {
connection = DriverManager.getConnection(jdbcDriver, dbUser, dbPass);
connection.setAutoCommit(false);
// 쿼리 여러 개 실행
connection.commit();
} catch (SQLException ex) {
// exception 발생 시
connection.rollback();
}
✉️ Connection Pool
- 데이터베이스와 연결된 커넥션을 미리 만들어 Pool에 저장해두고 있다가 필요할 때에 커넥션을 풀에서 가져다 쓰고 다시 반환하는 기법을 의미
- 풀 속에 미리 커넥션을 생성해 두었기 때문에 커넥션을 생성하는데 드는 연결 시간을 줄일 수 있다.
- 커넥션을 계속해서 재사용하기 때문에 생성되는 커넥션수가 일정하게 유지