개발자교육

24_07_17 오늘의 수업내용

regnator 2024. 7. 22. 13:26
728x90
반응형

JDBC 연결 및 오류 처리

1단계: MySQL 드라이버 로딩

Class.forName("com.mysql.jdbc.Driver");
  • mysql-connector-java-8.0.28.jar 파일 안에 있는 Driver 클래스를 로딩.
  • 만약 WEB-INF/lib 디렉토리에 mysql-connector-java-8.0.28.jar 파일이 없다면 에러가 발생.

main>web-inf>lib안에 mysql-connector-java-8.0.28.jar(Driver.class) 미존재시 에러발생

 

2단계: 데이터베이스 연결 정보 설정

정상 연결 예시:

Connection conn = null;
PreparedStatement pstmt = null;
String jdbcDriver = "jdbc:mysql://localhost:3306/dev52db?useUnicode=true&characterEncoding=euckr";
String dbUser = "dev52id";
String dbPass = "dev52pw";

 

3단계: DB 연결 오류 예시

1) 잘못된 JDBC URL 프로토콜

String jdbcDriver = "jdbc:oracle://localhost:3306/dev52db?useUnicode=true&characterEncoding=euckr";
  • 에러: java.sql.SQLException: No suitable driver found for jdbc:oracle://localhost:3306/dev52db?useUnicode=true&characterEncoding=euckr

2) 포트번호를 mysql의 3306대신 다른것을 입력한 경우

String jdbcDriver = "jdbc:mysql://localhost:1521/dev52db?useUnicode=true&characterEncoding=euckr";
  • 에러 : java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:1521/dev52db?useUnicode=true&characterEncoding=euckr

 

3) 기존에 만들어 놓은 데이터베이스명(dev52db)과 다른것을 사용한 경우

String jdbcDriver = "jdbc:mysql://localhost:3306/dev525123431db?useUnicode=true&characterEncoding=euckr";
  • 에러 : java.sql.SQLException: Unknown database 'dev525123431db'
 

4) 데이터베이스 접속아이디(dev52id)를 다르게 입력한 경우

String dbUser = "dev52213153id";
String dbPass = "dev52pw";
  • 에러 : java.sql.SQLException: Access denied for user 'dev52213153id'@'localhost' (using password: YES)

 


5) 데이터베이스 접속 아이디에 맞지 않는 비밀번호(dev52pw)를 입력한 경우

String dbUser = "dev52id";
String dbPass = "dev52213124123pw";
  • 에러 : java.sql.SQLException: Access denied for user 'dev52id'@'localhost' (using password: YES)

 

 

JDBC Connection 처리 및 메서드 구현 요약

1. 드라이버 로딩 및 DB 연결 정보 설정

1) 드라이버 로딩

Class.forName("com.mysql.jdbc.Driver");
  • MySQL 드라이버를 로딩한다. mysql-connector-java-8.0.28.jar 파일이 WEB-INF/lib에 있어야 한다.

 

2) DB 연결 정보 설정

String jdbcDriver = "jdbc:mysql://localhost:3306/dev52db?useUnicode=true&characterEncoding=euckr";
String dbUser = "dev52id";
String dbPass = "dev52pw";
 

3) 데이터베이스 연결 시도

Connection conn = DriverManager.getConnection(jdbcDriver, dbUser, dbPass);
  • 데이터베이스 연결을 시도. conn 객체가 null이 아니고, conn.isClosed()가 false이면 연결이 정상적으로 된 것이다.

 

2. Connection 인터페이스 및 구현 클래스

1) Connection 인터페이스

  • 두 개의 추상 메서드가 선언되어 있다:
public interface Connection {
    PreparedStatement prepareStatement(String sql) throws SQLException;
    void close() throws SQLException;
}

 

2) ConnectionImpl 클래스

  • Connection 인터페이스를 구현하는 클래스이다. 두 추상 메서드를 구현해야 한다.
public class ConnectionImpl implements Connection {
    @Override
    public PreparedStatement prepareStatement(String sql) {
        return new ClientPreparedStatement(sql);
    }

    @Override
    public void close() {
        System.out.println("Connection closed");
    }
}

 

3. PreparedStatement 인터페이스 및 구현 클래스

1) PreparedStatement 인터페이스

주요 메서드:

public interface PreparedStatement {
    void setString(int parameterIndex, String x) throws SQLException;
    int executeUpdate() throws SQLException;
    void close() throws SQLException;
}

 

2) ClientPreparedStatement 클래스

  • PreparedStatement 인터페이스를 구현:
public class ClientPreparedStatement implements PreparedStatement {
    private String sql;

    public ClientPreparedStatement(String sql) {
        this.sql = sql;
    }

    @Override
    public void setString(int parameterIndex, String x) {
        System.out.println("3-2단계 : 쿼리실행준비 ClientPreparedStatement.java");
    }

    @Override
    public int executeUpdate() {
        System.out.println("5단계 : 쿼리실행 ClientPreparedStatement.java");
        return 1;
    }

    @Override
    public void close() {
        System.out.println("6단계 : 객체종료 ClientPreparedStatement.java");
    }
}

 

4. executeQuery 메서드 처리 과정

  1. 쿼리 실행 후 결과를 담고 응용할 수 있는 ResultSetImpl 클래스 객체 생성
  2. ResultSetImpl 객체 내에 쿼리 실행 결과를 담음
  3. ResultSetImpl 객체 주소값을 호출한 곳으로 리턴
public class ClientPreparedStatement implements PreparedStatement {
    // Other methods...

    public ResultSet executeQuery() {
        System.out.println("Executing query...");
        ResultSetImpl resultSet = new ResultSetImpl();
        // Simulate filling the ResultSet with data
        resultSet.fillData();
        return resultSet;
    }
}

public class ResultSetImpl implements ResultSet {
    // Method to simulate filling data
    public void fillData() {
        System.out.println("Filling ResultSet with data...");
    }
}

 

전체 요약

1. 드라이버 로딩 및 DB 연결 정보 설정

Class.forName("com.mysql.jdbc.Driver");
String jdbcDriver = "jdbc:mysql://localhost:3306/dev52db?useUnicode=true&characterEncoding=euckr";
String dbUser = "dev52id";
String dbPass = "dev52pw";
Connection conn = DriverManager.getConnection(jdbcDriver, dbUser, dbPass);
 

2. Connection 인터페이스 및 ConnectionImpl 클래스

  • prepareStatement 및 close 메서드를 구현

 

3. PreparedStatement 인터페이스 및 ClientPreparedStatement 클래스

  • setString, executeUpdate, close 메서드를 구현

4. 쿼리 실행 및 결과 처리

  • executeQuery 메서드에서 ResultSetImpl 객체를 생성하고 데이터를 담아 반환

 

JDBC 관련 인터페이스 및 클래스 설명

1. Connection 인터페이스

  • 역할: 데이터베이스와의 연결을 나타낸다.
  • 주요 메서드:
    1. PreparedStatement prepareStatement(String sql) - SQL 쿼리를 실행하기 위해 PreparedStatement 객체를 반환.
    2. void close() - 데이터베이스 연결을 닫음.
  • 이유: 데이터베이스와 연결된 상태를 유지하고, SQL 쿼리를 실행할 수 있게 한다.
public interface Connection {
    PreparedStatement prepareStatement(String sql) throws SQLException;
    void close() throws SQLException;
}

 

2. ConnectionImpl 클래스

  • 역할: Connection 인터페이스를 구현하여 실제 데이터베이스와의 연결을 처리.
  • 주요 메서드:
    1. PreparedStatement prepareStatement(String sql) - ClientPreparedStatement 객체를 생성하여 반환.
    2. void close() - 연결을 종료하는 기능을 구현.
  • 이유: 데이터베이스와의 실제 연결을 처리하고 Connection 인터페이스의 추상 메서드를 구현하여 사용.
public class ConnectionImpl implements Connection {
    @Override
    public PreparedStatement prepareStatement(String sql) {
        return new ClientPreparedStatement(sql);
    }

    @Override
    public void close() {
        System.out.println("Connection closed");
    }
}

3. PreparedStatement 인터페이스

  • 역할: SQL 쿼리를 실행하기 위한 인터페이스.
  • 주요 메서드:
    1. void setString(int parameterIndex, String x) - SQL 쿼리의 매개변수를 설정.
    2. int executeUpdate() - 데이터베이스에 대한 INSERT, UPDATE, DELETE 문을 실행.
    3. void close() - PreparedStatement 객체를 닫음.
  • 이유: SQL 쿼리를 안전하게 실행하고, 매개변수를 바인딩하여 SQL 인젝션 공격을 방지.
public interface PreparedStatement {
    void setString(int parameterIndex, String x) throws SQLException;
    int executeUpdate() throws SQLException;
    void close() throws SQLException;
}

 

4. ClientPreparedStatement 클래스

  • 역할: PreparedStatement 인터페이스를 구현하여 실제 SQL 쿼리를 실행.
  • 주요 메서드:
    1. void setString(int parameterIndex, String x) - 매개변수 설정을 위한 실제 구현.
    2. int executeUpdate() - 데이터베이스에 대한 SQL 쿼리를 실행.
    3. void close() - PreparedStatement 객체를 닫음.
  • 이유: PreparedStatement 인터페이스의 추상 메서드를 구현하여 사용자가 SQL 쿼리를 실행하고, 매개변수를 설정할 수 있게 함.
public class ClientPreparedStatement implements PreparedStatement {
    private String sql;

    public ClientPreparedStatement(String sql) {
        this.sql = sql;
    }

    @Override
    public void setString(int parameterIndex, String x) {
        System.out.println("3-2단계 : 쿼리실행준비 ClientPreparedStatement.java");
    }

    @Override
    public int executeUpdate() {
        System.out.println("5단계 : 쿼리실행 ClientPreparedStatement.java");
        return 1;
    }

    @Override
    public void close() {
        System.out.println("6단계 : 객체종료 ClientPreparedStatement.java");
    }
}

 

5. ResultSet 인터페이스

  • 역할: SQL 쿼리의 결과 집합을 나타냅니다. 결과를 순회하며 데이터베이스에서 검색한 데이터를 읽는다.
  • 주요 메서드: (구현 필요)
  • 이유: SELECT 쿼리의 결과를 처리하고, 결과 집합을 순회하며 데이터를 읽을 수 있게 함.
public interface ResultSet {
    boolean next() throws SQLException; // ResultSet 내의 다음 행으로 이동
    String getString(String columnLabel) throws SQLException; // 열 값 가져오기
    void close() throws SQLException; // ResultSet 닫기
}

 

6. ResultSetImpl 클래스

  • 역할: ResultSet 인터페이스를 구현하여 실제로 SQL 쿼리의 결과를 처리.
  • 주요 메서드:
    1. boolean next() - 결과 집합에서 다음 행으로 이동.
    2. String getString(String columnLabel) - 특정 열의 값을 가져옴.
    3. void close() - ResultSet 객체를 닫음.
  • 이유: ResultSet 인터페이스의 추상 메서드를 구현하여 사용자가 쿼리 결과를 처리할 수 있게 함.
public class ResultSetImpl implements ResultSet {
    @Override
    public boolean next() {
        // 실제로 결과 집합의 다음 행으로 이동하는 코드
        return false;
    }

    @Override
    public String getString(String columnLabel) {
        // 실제로 열 값을 가져오는 코드
        return null;
    }

    @Override
    public void close() {
        System.out.println("ResultSet closed");
    }

    // Method to simulate filling data
    public void fillData() {
        System.out.println("Filling ResultSet with data...");
    }
}

 

전체 흐름 요약

  1. 드라이버 로딩 및 DB 연결 정보 설정
    • 드라이버 로딩: Class.forName("com.mysql.jdbc.Driver");
    • DB 연결: Connection conn = DriverManager.getConnection(jdbcDriver, dbUser, dbPass);
  2. Connection 인터페이스 및 구현 클래스
    • ConnectionImpl 클래스가 Connection 인터페이스의 prepareStatement와 close 메서드를 구현.
  3. PreparedStatement 인터페이스 및 구현 클래스
    • ClientPreparedStatement 클래스가 PreparedStatement 인터페이스의 setString, executeUpdate, close 메서드를 구현.
  4. 쿼리 실행 및 결과 처리
    • ClientPreparedStatement 클래스의 executeQuery 메서드가 ResultSetImpl 객체를 생성하고 데이터를 담아 반환.
    • ResultSetImpl 클래스가 ResultSet 인터페이스의 next, getString, close 메서드를 구현.
728x90
반응형