ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 10.5 Database programming with Java
    데이터베이스 시스템 2024. 11. 26. 07:39

    Connections

    이 섹션에서는 Java와 MySQL을 사용한 데이터베이스 프로그래밍을 설명한다.
    Connector/J는 MySQL의 공식 JDBC(Java Database Connectivity) 드라이버이다.
    이 섹션은 Java 언어에 대한 기본적인 지식을 전제로 한다.

    Connector/J 설치

    더보기

    Connector/J 패키지는 Java 프로그램이 실행되는 컴퓨터에 설치되어야 한다. Connector/J를 다운로드하고 설치하는 방법은 Connector/J Installation에서 확인할 수 있다.

    Java 프로그램은 java.sql.Connection과 java.sql.DriverManager 클래스를 import하고 사용하여 MySQL 데이터베이스에 연결한다.

    Java 프로그램은 쿼리를 실행하기 전에 데이터베이스에 연결해야 한다.

    • 연결은 Connection 인터페이스의 객체로, DriverManager.getConnection() 메서드를 사용하여 생성된다.
    • 이 메서드는 데이터베이스 서버 주소, 데이터베이스 이름, 로그인 사용자 이름, 비밀번호를 지정한다.

    연결 실패 처리

    • 데이터베이스를 찾을 수 없거나 로그인 자격 증명이 유효하지 않으면 연결 생성이 실패한다.
    • 따라서 연결은 일반적으로 try-catch 문의 try 블록 내에서 생성된다.
    • 연결이 실패하면 catch 블록이 실행되며, 일반적으로 오류 메시지를 출력한다.

    Java 프로그램은 연결이 더 이상 필요하지 않을 때 connection.close() 메서드를 사용하여 연결을 해제한다.

    1. import 문은 Connector/J 코드를 프로그램에서 사용할 수 있도록 한다.
    2. DriverManager.getConnection() 메서드는 reservationConn이라는 Connection 객체를 생성한다.
    3. 연결이 성공하면 이후 쿼리는 reservationConn 객체를 사용한다. 데이터베이스 처리가 완료되면 close() 메서드를 호출하여 연결을 해제한다.
    4. 연결이 실패하면 catch 블록이 실행되며 SQLException 객체로부터 오류 메시지를 출력한다.

    Executing queries

    Statement 인터페이스는 SQL 쿼리를 정의하고 실행한다.
    Statement 객체는 Connection 인터페이스의 createStatement() 메서드로 생성된다.

    • Statement 객체는 항상 동일한 연결(따라서 동일한 데이터베이스)과 연관된다.
    • 그러나 Statement 객체는 서로 다른 쿼리로 여러 번 실행될 수 있다.

    Statement 메서드를 사용하여 SQL 쿼리를 정의하고 실행한다:

    1. executeQuery()
      • SELECT 쿼리와 Statement 객체를 연관시킨다.
      • 쿼리를 컴파일하고 실행한다.
      • 하나의 필수 매개변수로 SQL 쿼리를 포함하는 문자열을 받으며, ResultSet 객체를 반환한다(ResultSet은 아래에 설명됨).
    2. executeUpdate()
      • INSERT, UPDATE, DELETE 쿼리를 실행한다.
      • 수정된 행 수가 아니라 쿼리와 일치하는 행의 수를 반환한다.
    3. execute()
      • 모든 종류의 SQL 문을 실행할 수 있으나 주로 CREATE TABLE과 같은 데이터 정의문에 사용된다.
      • 부울 값을 반환하며, 값이 true인 경우 Statement의 getResultSet() 메서드를 사용하여 생성된 ResultSet 객체에 접근할 수 있다.
    4. close()
      • Statement 객체를 해제하며, 연관된 연결을 닫기 전에 실행되어야 한다.

    Statement 인터페이스를 Java 프로그램에서 사용하려면 import java.sql.Statement;를 포함해야 한다.

    1. createStatement 메서드는 Reservation 데이터베이스와 연관된 flightStatement라는 Statement 객체를 생성한다.
    2. execute()는 CREATE TABLE 문을 실행하여 Flight 테이블을 생성한다.
    3. executeUpdate()는 INSERT 문을 실행하여 Flight 테이블에 행을 삽입한다.
    4. close()는 Statement 객체의 자원을 해제한다.

    Fetching values

    Connector/J는 커서를 지원하지 않으며, 대신 ResultSet 인터페이스를 사용하여 쿼리 결과를 가져온다.

    1. executeQuery()
      • 쿼리 결과를 포함하는 ResultSet 객체를 반환한다.
      • ResultSet 객체는 쿼리 결과의 현재 행에 대한 포인터를 유지한다.
      • 처음에는 현재 행이 쿼리 결과의 첫 번째 행이다.
    2. next() 메서드
      • 현재 행을 다음 행으로 이동시킨다.
      • 이동이 성공하면 true를 반환하며, 마지막 행에 도달하면 false를 반환한다.
    3. 현재 행의 값 접근
      • ResultSet 메서드를 사용하여 현재 행의 값을 가져온다:
        • getInt(): 열 이름을 매개변수로 받아 해당 열의 정수 값을 반환한다.
        • getDouble(): 열 이름을 매개변수로 받아 해당 열의 Double 값을 반환한다.
        • getString(): 열 이름을 매개변수로 받아 해당 열의 문자열 값을 반환한다.
    4. 추가 정보 반환
      • getMetaData(): ResultSet 객체의 열에 대한 정보를 포함하는 ResultSetMetaData 객체를 반환한다.
      • getWarnings(): 쿼리에 의해 생성된 첫 번째 경고를 반환한다.

    ResultSet 인터페이스를 사용하려면 import java.sql.ResultSet;을 Java 프로그램에 포함해야 한다.

    1. flightStatement 객체는 SELECT 쿼리를 실행하고 ResultSet 객체를 반환한다.
    2. while 문은 next()를 호출하여 쿼리 결과의 각 행을 순차적으로 진행한다.
    3. 각 resultSet 행에 대해 FlightNumber와 DepartureTime 열의 값을 가져와 출력한다.
    4. close()는 resultSet 객체의 자원을 해제한다.

    Statement flightStatement = reservationConn.createStatement();
    String flightQuery = "SELECT AirlineName, DepartureTime, AirportCode FROM Flight "
       + "WHERE FlightNumber = '140'";
    
    ResultSet resultSet = flightStatement.___A___(flightQuery);
    int rows = 0;
    while(resultSet.___B___) {
       System.out.println(resultSet.getString("AirlineName") +
          " departs from " + resultSet.getString("AirportCode");
       rows++;
    }
    if (___C___) {
       System.out.println("Flight not found");
    }
    resultSet.close();

    ▼View answer

    더보기

    executeQuery

    next()

    rows == 0

     - 변수 rows는 루프 반복 횟수를 나타낸다.
    rows가 0이라면 루프 반복이 없었음을 의미하며, 따라서 항공편이 발견되지 않았다는 뜻이다.


    Query parameters

    PreparedStatement 인터페이스는 Statement 인터페이스를 확장하며 SQL 쿼리 매개변수를 지원한다.

    1. PreparedStatement 객체 생성
      • PreparedStatement 객체는 Connection 인터페이스의 prepareStatement() 메서드를 사용하여 생성된다.
      • prepareStatement()는 SQL 쿼리 문자열을 매개변수로 받으며, createStatement()와 달리 매개변수가 필요하다.
    2. 상속된 메서드
      • PreparedStatement는 Statement로부터 executeQuery()와 executeUpdate() 메서드를 상속받는다.
      • 그러나 PreparedStatement 메서드는 쿼리 매개변수를 받지 않는다.
        • 이유: PreparedStatement는 생성 시 이미 쿼리가 지정되기 때문이다.
    3. SQL 쿼리 매개변수 지원
      • SQL 쿼리는 하나 이상의 ? 문자를 포함하여 쿼리 매개변수를 나타낸다.
      • PreparedStatement 메서드(setString(), setInt() 등)를 사용하여 placeholder(?)에 값을 할당한다.
        Ex: preparedStatement.setString(1, flightNumber)는 PreparedStatement 객체의 첫 번째 물음표를 flightNumber 문자열 값으로 설정한다.
    4. SQL injection attack
      • 데이터베이스 프로그래머는 입력 데이터를 SQL 문에 삽입할 때 주의해야 한다.
      • SQL injection attack은 사용자가 SQL 문 의도를 변경하는 값을 고의로 입력하는 경우 발생한다.
      • preparedStatement.executeQuery() 메서드는 placeholder에 값을 할당할 때 SQL injection attack을 방지한다.
    1. 사용자가 항공편 데이터를 입력한다.
    2. flightInsert는 세 개의 ? placeholder를 포함하며, 값은 준비된 문장이 실행될 때 할당된다.
    3. PreparedStatement 객체는 flightInsert 문자열에 있는 SQL 문으로 생성된다.
    4. executeUpdate()가 실행되면 Java 값이 placeholder에 할당된다. Java 데이터 타입은 자동으로 MySQL 데이터 타입으로 변환된다.
    5. close()는 PreparedStatement 객체의 자원을 해제한다.

    Stored  procedure calls

    저장 프로시저는 MySQL 절차적 SQL의 일부로, 데이터베이스에 저장되며 Java와 같은 범용 프로그래밍 언어에서 자주 호출된다.

    • IN 매개변수: 저장 프로시저에 데이터를 입력한다.
    • OUT 매개변수: 저장 프로시저에서 데이터를 출력한다.

    CallableStatement 인터페이스는 PreparedStatement를 확장하며 저장 프로시저를 호출하는 메서드를 제공한다.

    1. CallableStatement 객체 생성
      • Connection 인터페이스의 prepareCall() 메서드를 사용하여 생성된다.
    2. 저장 프로시저 실행
      • CallableStatement의 executeQuery() 메서드로 저장 프로시저를 실행한다.
    3. 매개변수와 Java 값의 연결
      • setInt(): IN 매개변수를 지정된 Java int 값으로 설정한다.
      • setString(): IN 매개변수를 지정된 Java String 값으로 설정한다.
      • registerOutParameter(): OUT 매개변수를 지정된 JDBC 타입으로 설정한다.
    1. FlightCount 저장 프로시저는 특정 항공사의 항공편 수를 계산한다.
    2. prepareCall() 메서드는 CallableStatement 객체를 생성한다.
    3. setString()은 항공사 매개변수에 값을 바인딩하고, registerOutParameter()는 quantity 매개변수에 값을 바인딩한다. executeQuery()는 저장 프로시저를 실행한다.
    4. getString(2)는 quantity 매개변수를 반환한다.

    Connection roomConn - null;
    roomConn = DriverManager.______(A)______("jdbc:mysql://127.0.0.1/reservation?"
        	+ "user=samsnead&password=*jksi72$");
    String roomQuery = "SELECT RoomNumber FROM Room WHERE FloorNumber = ?";
    PreparedStatement roomStatement = roomConn.______(B)______(roomQuery);
    roomStatement.______(C)______(1, 3);
    ResultSet resultSet = ______(D)______.executeQuery();
    while (resultSet.next()) {
    	System.out.printIn("Found room " + resultSet.______(E)______("RoomNumber") + " located on the 3rd floor.");
    }
    ______(F)______.close();
    roomStatement.close();
    roomConn.______(G)______();

    ▼View answers

    더보기

    (A) getConnection (B) prepareStatement (C) setInt (D) roomStatement (E) getInt (F) resultSet (G) close

     

Designed by Tistory.