전낙타 2023. 9. 8. 18:15

JDBC

Java DataBase Connectivity

⇒ 자바가 DBMS와 연동하기 위한 기술

오라클에 접속하여 JDBC를 사용하기 전에 해야할일

  1. 오라클 드라이버를 다운로드
    • 모든 DBMS의 제조사 홈페이지에서 다운로드
    • 오라클이 설치되어 있는 경우 (XE)

      C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib의 ojdbc.jar파일

      ojdbc.jar파일 : 오라클 드라이버

  1. JVM이 인식할 수 있는 위치로 오라클 드라이버를 복사

    ⇒ 코드를 실행하기 위해서 JVM이 찾을 수 있는 위치

    ⇒ Build path에서 라이브러리 등록(Appllication 이므로, 웹인경우 lib에 복사)

자바로 DBMS 연동

  1. oracle 드라이버 로딩

    클래스 로더를 이용해서 드라이버의 핵심 클래스를 메모리에 로딩

    java.lang 패키지의 Class라는 클래스의 forName이라는 메소드를 이용해서 오라클 드라이버의 핵심 클래스를 메모리에 로딩

    핵심 클래스는 드라이버 클래스라 하고 이 드라이버 클래스는 어떤 DBMS를 쓰냐에 따라 달라진다.

    [문법]

    Class.forName(”핵심 클래스의 full path - 패키지를 포함한 클래스명”)

    [오라클]

    Class.forName(”oracle.jdbc.driver.OracleDriver”) : 오라클 드라이버라고 한다

    [mysql]

    Class.forName(”com.mysql.cj.jdbc.Driver”) : mysql 드라이버

  1. DB 서버에 연결

    ⇒ java.sql패키지의 API를 이용

    public static Connecttion getConnection(String url, String user, String password)

    throws SQLException

    1. static 메소드이므로 클래스명으로 엑세스

      DriverManager.getConnection

    1. throws하고 있는 SQLException은 Exception클래스의 하위으므로 문법적으로 Exception에 대한 처리를 해야한다.
    1. 매개변수

      url : 연결문자열 (어떤 DBMS를 쓰느냐에 따라 내부에서 인식될 문자열을 다른 형식으로 만들어서 넘기기)

      [오라클]

      jdbc:oracle:thin:@ip:port:데이터베이스서비스명

      jdbc:oracle:thin : 오라클에서 사용하는 프로토콜

      @ip:port : DBMS가 설치되어 있는 서버의 ip와 접속prot(1521)

      데이터베이스서비스명 : 오라클 설치할때 설정하는 값으로 express edition버전은 xe

      [mysql]

      jdbc:mysql://ip:port/데이터베이스명?serverTimezone=UTC

      ex) 현재 작업중인 pc(로컬) 127.0.0.1 or localhost

      jdbc:oracle:thin:@127.0.0.1:1521:xe

      jdbc:oracle:thin:@localhost:1521:xe

      jdbc:oracle:thin:@내컴퓨터IP:1521:xe

      user : 사용자계정(scott)

      password : 계정의 패스워드(tiger)

    1. 리턴타입

      java.sql.Connection을 리턴

      DriverManager.getConnection클래스의 getConnection메소드는 매개변수로 전달받은 값을 활용해서 DB서버에 연결하고 연결정보를 객체로 만들어서 리턴

      객체 : java.sql.Connection의 하위 클래스

      ⇒ 어떤 드라이버가 로딩되냐에 따라 Connection의 하위지만 각각 다른 클래스가 매핑

  1. SQL 문을 실행하기 위한 객체 생성

    Connection 객체의 메소드를 이용해서 SQL문을 실행하기 위한 객체를 생성

    [상속구조]

    Statement

    PreparedStatement

    callableStatement

    statment - 정적 SQL을 실행할때 사용 (보안취약)

    PreparedStatement - 동적 SQL을 실행할때 사용(시큐어코딩에 적합한 방식, 캐시사용)

    callableStatement - 각 DBMS에 특화된 SQL로 작성된 명령문을 실행

    ⇒ SQL 문을 실행하기 위한 메소드를 갖고있는 클래스

    1. Statement객체를 이용

      Connection 객체가 갖고 있는 createStatement메소드를 이용해서 생성

      [형식]

      Statement stmt = con.createStatement()

      : 어떤 DBMS가 로딩되어 있느냐에 따라 다른 Statement객체가 만들어짐

    1. PreparedStatement객체를 이용

      Connection 객체가 갖고 있는 prepareStatement메소드를 이용해서 생성

  1. SQL문을 실행
    1. Statement 객체 사용
      1. executeUpdate : insert, update, delete 명령문을 실어, 매개변수로 전달된 sql문을 실행, 결과로 몇개의 row가 반영되었는지 리턴

        int result = stmt.executeUpdate(sql문)

        몇개의 행이 삽입, 삭제, 수정됐는지 리턴

      1. excuteQuery : select명령문을 실행, 실행한 후 조회된 테이블을 리턴, DBMS에서 조회된 테이블을 자바에서 사용할 수 있도록 만들어 놓은 객체가 ResultSet, 실제 어떤 DBMS가 사용되었는징 따라 다른 ResultSet 객체(ResultSet의 하위객체) 가 리턴

    1. PreparedStatement 객체를 사용

      Connection객체가 갖고있는 prepareStatement메소드를 이용해서 생성

      캐시사용

      • 쿼리문장 문석
      • 컴파일
      • 실행

        Statement는 SQL을 실행하는 과정에서 매번 위의 3가지 내용을 처리하고 있지만 PrepareStatement는 한번만 작업하고 캐시에서 꺼내서 사용

      PreparedStatement객체가 sql문을 실행하는 방식은 SQL을 미리 파싱해놓고 외부에서 입력받는 값을 전달해서 실행할 수 있도록 처리

      1. sql문을 매개변수로 넘기면서 PrepatedStatement 객체를 생성

      ⇒ sql문을 미리 파싱하는방법이므로 Connection 객체의 prepateStatement메소드를이용해서 PreparedStatement객체를 만들때 sql문을 전달

      PrepareStatement ptmp = con.prepareStatement(sql)

      1. sql문을 작성할 때 외부에서 입력받아 처리되는 부분을 ? 로 대체하여 표시한 후 작성

        String sql = “select * from member where id=? and pass=?”

        ⇒ 값에 대한 부분만 ?처리 (컬럼명 ?로 처리 못함)

        ⇒ 값의 자리에는 ?만 올 수 있음( ‘?’ 는 인식 못함)

      1. ?에 대한 값 셋팅

        ?는 외부에서 입력받은 값으로 셋팅해야 하므로 메소드를 이용해서 설정

        setXXX 메소드를 타입과 연결해서 알맞는 setter 메소드를 선택

        ptmt.setString(1,”jang”) ⇒ 첫번째 ?에 jang을 대입

  1. 결과처리
    1. insert, delete, update
      • 모두 int를 리턴하므로 동일한 방법으로 처리
    1. select
      • 2차원 표로 리턴되어 보이는 테이블에 저장된 자바에서 사용할 수 있도록 만들어진 객체가 ResultSet
      • select문을 실행하면 executeQuery메소드가 ResultSet을 리턴하기 때문에 ResultSet 타입의 변수를 선언해서 저장

        ResultSet rs = stmt.executeQuery(sql문)

      • ResultSet에 있는 테이블의 테이터를 읽기 위해서는 ResultSet의 메소드를 이용해서 작업
      • Cursor를 다음 레코드로 이동하면서 레코드가 있으면 레코드 갯수만큼 반복작업

        while (rs.next()) { → true/false를 리턴(레코드가 있으면 true를 리턴, 없으면 false)

        // 레코드의 각 컬럼을 읽는다.

        }

      • 한번에 하나의 컬럼만 읽을 수 있다.
      • getXXX 메소드를 이용해서 컬럼값을 읽는다.
      • 타입에 따라서 선택

        오라클 타입 varchar2 or char : java의 String , getString (컬럼명 or getString(컬럼순서index)

        컬럼순서 index → 원본데이터의 컬럼순서가 아니라 조회된 테이블에 포함된 컬럼순서

        오라클 타입 number : java의 int , getInt(컬럼명) or getInt(컬럼순서index)

        오라클 타입 date : java의 java.sql.Date, getDate(컬럼명) or getDate(컬럼순서index)

  1. 자원 반납

    클라이언트가 점유해서 사용하던 자원을 반납해야 한다.

    Connection, Statement, ResultSet 까지 모든 자원을 반납

    close메소드를 이용해서 처리

    만들어진 순서가 아니라 제일 마지막에 생성된 객체부터 반납한다.