[JDBC] 1. JavaDatabseConnectivity

Nam_JU·2022년 7월 23일
0

KaKao Cloud School

목록 보기
14/19

JDBC(Java Databse Connectivity)

  • JDBC는 자바 클래스와 인터페이스의 집합이다

자바프로그램이 여러 데이터베이스에 접속하려면 데이터베이스 구조 구현에 따라야 한다. 직접적으로 데이터베이스에 붙어서 하려면 코드를 달리 작성해줘야 하는 문제가 생긴다. 유지보수와 재활용성에 문제점이 생김.
이 문제를 해결하기위해 공통의 인터페이스를 제공하는것이 JDBC이다

  • JDBC Driver
    • 해당 인터페이스를 사용할 수 있도록 구현해놓은 것

    • 이것을 만든게 jdbc bender

    • 각각의 회사에서 만든 jdbc Driver드라이버 클래스를 제공한다

    • 실제 데이터베이스를 사용할 수 있도록!

    • jdbc vender(판매자들)이 jdbc Driver 클래스를 작성해서 배포함


JDBC Driver loading 작업

  1. 사용하는 데이터베이스에 맞는 driver class를 등록
    1-1. Class라는 class를 사용
    1-2. DriverManager Class 사용
    Class.*forName*("com.mysql.cj.jdbc.Driver"); //forName: drive 부터 로딩한다


  2. DBMS와 연결 (실제 데이터베이스연결하는 부분) - Connection 객체 생성
    • 접속에 성공하면 JDBC에 있는 인터페이스 중 하나인 connection이라는 인스턴스(객체)가 생성된다
    • 하지만 부하가 많이 걸린다
    • 데이터베이스는 세션이 한정적이다 사용후 닫아줘야 한다
    • 데이터베이스와 연결후 → 성공후 인스턴스를 만들 수 있다. 데이터베이스는 한번에 열수있는세션이 한정적이기 때문에 다 쓰고난 후 close로 닫아줘야 한다. 그래야 데이터베이스 쪽에서 세션을 닫을 수 있다
  • JDBC URL
    - 형식이 정해져있다
    - JDBC URL + ID+ PW 입력후 connection을 생성

  1. statement 객체 생성
  • 일반 Statement 객체
  • Prepared Statement (일반 statement의 개량형)
  • Callable statement → stored procedure를 호출할때 사용
    우리는 Prepared Statment를 사용

Prepared Statment

  • 쿼리에 대한 변환 작업을 미리 statement에 넣어 두는 것
    마치 캐시와 같은 역할을 해주기 때문에 많은 양의 쿼리를 실행해야 할때 속도면에서 이점을 얻을 수 있다
  • 데이터베이스 인젝션을 예방할 수 있다
    Prepared Statment는 쿼리가 한번들어오면 고정되어서 외부의 입력으로 변경이 불가능해짐
  • Prepared Statment는 인파라미터를 사용할 수 있다
    DELETE FROM buytbl WHERE userID = ? ? 여러개 사용 가능


  1. 쿼리 실행
  • execute() : 4개 상태 전부 가능하지만 나온결과를 판단해서 개발자가 처리해야한다
  • 내가쓰는게 뭔지 모르고 동적으로 변경이 될경우 사용
  • 정해지지 않은경우 아래의 방법들을 사용함 (보편적으로 사용한다)
  • executeQuery() : select 계열의 결과 레코드 집합을 호출하는 쿼리 수행
  • executeUpdate() : Insert, update, delete 계열의 쿼리를 수행할때

  1. 결과 쿼리
    ResultSet rs = psrat.executeQuery();
  • rs.next() 할때마다 행(row)을 가리키는 커서(cursor)가 다음행으로 하나씩 실행
    • 다음행이 존재하면 true
    • 다음행이 존재하지 않으면 false
  • rs.getString() 가져온 값을 자바String 형태로 변경
    - rs.getString(”name”)
    - rs.getString(2) index는 1부터 시작이다 0부터 넣으면 안됨!
public class Main {
    public static void main(String[] args) {
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs2 = null;

        //1. JDBC driver loading - 내가사용하는 데이터베이스의 드라이버 클래스명을 입력
        // MySQL8.0부터는 아래의 class 를 사용한다
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("드라이버 로딩 성공");

        //2. 실제 데이터베이스에 연결    프로토콜        DBMS   스키마명                         //타임존
            String jdbcURL = "jdbc:mysql://localhost:3306/sqldb?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
             // 접속에 성공하면 Connection 이라는 객체가 생긴다
            con = DriverManager.getConnection(jdbcURL,"root","kim8480848");
            System.out.println("데이터베이스 연결 성공");

            String sql = "SELECT userID, name, addr FROM usertbl";
        //3. Statement 생성
            //3-2 PreparedStatement
             pstmt = con.prepareStatement(sql);

        //4. 쿼리 실행
            //Statement 를 사용해서 sql 쿼리를 DBMS 에 실제로 전달한다
                //전처리된 sql 문장 실행
           rs2 = pstmt.executeQuery();

         //5. 결과 처리
            //가져온값 전체를 돌아라 .next() 끝에 도달하면 false가 나옴
        while (rs2.next()){
            String id = rs2.getString(1);
            String name = rs2.getString(2);
            String addr = rs2.getString(3);
            System.out.println(id + ", " + name + ", " + addr);
        }

        } catch (ClassNotFoundException e) { //Class.forName
            throw new RuntimeException(e);
        } catch (SQLException e2) {  //DriverManager.getConnection
            throw new RuntimeException(e2);
        }finally {
            //finally exception이 뜨거나 말거나 무조건 실행
            try {
                //자원들을 각각하나씩 해제 해야한다
                if (rs2 != null) rs2.close();
                if (pstmt != null) pstmt.close();
                if (con != null)
                    con.close(); //자원을 아끼기 위해 닫아주기
            }catch (Exception e){
            }
        }

    }
}

데이터베이스를 여러명이 사용할 경우에 생기는 문제

  • 여러사람이 접속하려고 하면 여러개의 스레드가 만들어진다
    데이터베이스의 부하가 증가
    - 세션만들고 → 생성하고 → 삭제하고 → 반복호출
    - 데이터베이스에는 세션의 갯수가 제한되어 있다

Connection Pool

  • 커넥션을 필요할때마다 만들지 않고 미리 만들어서 재사용이 가능하도록 한다
  • 동시에 많은 사용자에 대해 Databse 처리를 제공하려면?
    • 하나의 커넥션 객체를 여러명에게 공유하는 방법은?
      • transaction 문제가 생긴다
      • 한사람이 transaction을 사용해서 쭉 사용하고 있으면 다른 사람이 rollbak시켜버리면 날라가버려서 오작동이됨
        transaction은 공유를 못함!
    • Pooling 기법을 사용한다
      • 생성→ 소멸 생성→소멸 하지 않고
        자주 사용되는 객체들을 pool 이라는 곳에 만들어둬서 빌려주고 돌려받고 다시 빌려주는 방향
      • 자원에 대한 효율성을 높일 수 있다
  • 속도를 향상 시켜준다
  • 자원의 효율성
  • connection 부분 제어가 가능하다

DBCP

  • Apache commons의 DBCP를 사용하여 ConnectionPool을 만든다
  • 아파치 커먼즈는 재사용 가능한 자바 기반의 컴포넌트를 모아놓은 통합 프로젝트이다.

Layerd Architecture

  • 사용자에게 입력을 받고 계층을 분리하자



참고자료
[Java] JDBC를 사용한 데이터베이스 연동(Mysql)
SQL injection 대응 : Prepared Statement

profile
개발기록

0개의 댓글