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&param1=value2&...]
  • 웹 어플리케이션 구동할 때 한 번만 로딩되도록 구현하면 된다. 
    • 서블릿의 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 발생시킨다. 
  • 쿼리 실행을 위한 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 종료
  • 데이터베이스 커넥션 종료 
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에 저장해두고 있다가 필요할 때에 커넥션을 풀에서 가져다 쓰고 다시 반환하는 기법을 의미 
  • 풀 속에 미리 커넥션을 생성해 두었기 때문에 커넥션을 생성하는데 드는 연결 시간을 줄일 수 있다.
  • 커넥션을 계속해서 재사용하기 때문에 생성되는 커넥션수가 일정하게 유지