-
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() 메서드를 사용하여 연결을 해제한다.
- import 문은 Connector/J 코드를 프로그램에서 사용할 수 있도록 한다.
- DriverManager.getConnection() 메서드는 reservationConn이라는 Connection 객체를 생성한다.
- 연결이 성공하면 이후 쿼리는 reservationConn 객체를 사용한다. 데이터베이스 처리가 완료되면 close() 메서드를 호출하여 연결을 해제한다.
- 연결이 실패하면 catch 블록이 실행되며 SQLException 객체로부터 오류 메시지를 출력한다.
Executing queries
Statement 인터페이스는 SQL 쿼리를 정의하고 실행한다.
Statement 객체는 Connection 인터페이스의 createStatement() 메서드로 생성된다.- Statement 객체는 항상 동일한 연결(따라서 동일한 데이터베이스)과 연관된다.
- 그러나 Statement 객체는 서로 다른 쿼리로 여러 번 실행될 수 있다.
Statement 메서드를 사용하여 SQL 쿼리를 정의하고 실행한다:
- executeQuery()
- SELECT 쿼리와 Statement 객체를 연관시킨다.
- 쿼리를 컴파일하고 실행한다.
- 하나의 필수 매개변수로 SQL 쿼리를 포함하는 문자열을 받으며, ResultSet 객체를 반환한다(ResultSet은 아래에 설명됨).
- executeUpdate()
- INSERT, UPDATE, DELETE 쿼리를 실행한다.
- 수정된 행 수가 아니라 쿼리와 일치하는 행의 수를 반환한다.
- execute()
- 모든 종류의 SQL 문을 실행할 수 있으나 주로 CREATE TABLE과 같은 데이터 정의문에 사용된다.
- 부울 값을 반환하며, 값이 true인 경우 Statement의 getResultSet() 메서드를 사용하여 생성된 ResultSet 객체에 접근할 수 있다.
- close()
- Statement 객체를 해제하며, 연관된 연결을 닫기 전에 실행되어야 한다.
Statement 인터페이스를 Java 프로그램에서 사용하려면 import java.sql.Statement;를 포함해야 한다.
- createStatement 메서드는 Reservation 데이터베이스와 연관된 flightStatement라는 Statement 객체를 생성한다.
- execute()는 CREATE TABLE 문을 실행하여 Flight 테이블을 생성한다.
- executeUpdate()는 INSERT 문을 실행하여 Flight 테이블에 행을 삽입한다.
- close()는 Statement 객체의 자원을 해제한다.
Fetching values
Connector/J는 커서를 지원하지 않으며, 대신 ResultSet 인터페이스를 사용하여 쿼리 결과를 가져온다.
- executeQuery()
- 쿼리 결과를 포함하는 ResultSet 객체를 반환한다.
- ResultSet 객체는 쿼리 결과의 현재 행에 대한 포인터를 유지한다.
- 처음에는 현재 행이 쿼리 결과의 첫 번째 행이다.
- next() 메서드
- 현재 행을 다음 행으로 이동시킨다.
- 이동이 성공하면 true를 반환하며, 마지막 행에 도달하면 false를 반환한다.
- 현재 행의 값 접근
- ResultSet 메서드를 사용하여 현재 행의 값을 가져온다:
- getInt(): 열 이름을 매개변수로 받아 해당 열의 정수 값을 반환한다.
- getDouble(): 열 이름을 매개변수로 받아 해당 열의 Double 값을 반환한다.
- getString(): 열 이름을 매개변수로 받아 해당 열의 문자열 값을 반환한다.
- ResultSet 메서드를 사용하여 현재 행의 값을 가져온다:
- 추가 정보 반환
- getMetaData(): ResultSet 객체의 열에 대한 정보를 포함하는 ResultSetMetaData 객체를 반환한다.
- getWarnings(): 쿼리에 의해 생성된 첫 번째 경고를 반환한다.
ResultSet 인터페이스를 사용하려면 import java.sql.ResultSet;을 Java 프로그램에 포함해야 한다.
- flightStatement 객체는 SELECT 쿼리를 실행하고 ResultSet 객체를 반환한다.
- while 문은 next()를 호출하여 쿼리 결과의 각 행을 순차적으로 진행한다.
- 각 resultSet 행에 대해 FlightNumber와 DepartureTime 열의 값을 가져와 출력한다.
- 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 쿼리 매개변수를 지원한다.
- PreparedStatement 객체 생성
- PreparedStatement 객체는 Connection 인터페이스의 prepareStatement() 메서드를 사용하여 생성된다.
- prepareStatement()는 SQL 쿼리 문자열을 매개변수로 받으며, createStatement()와 달리 매개변수가 필요하다.
- 상속된 메서드
- PreparedStatement는 Statement로부터 executeQuery()와 executeUpdate() 메서드를 상속받는다.
- 그러나 PreparedStatement 메서드는 쿼리 매개변수를 받지 않는다.
- 이유: PreparedStatement는 생성 시 이미 쿼리가 지정되기 때문이다.
- SQL 쿼리 매개변수 지원
- SQL 쿼리는 하나 이상의 ? 문자를 포함하여 쿼리 매개변수를 나타낸다.
- PreparedStatement 메서드(setString(), setInt() 등)를 사용하여 placeholder(?)에 값을 할당한다.
Ex: preparedStatement.setString(1, flightNumber)는 PreparedStatement 객체의 첫 번째 물음표를 flightNumber 문자열 값으로 설정한다.
- SQL injection attack
- 데이터베이스 프로그래머는 입력 데이터를 SQL 문에 삽입할 때 주의해야 한다.
- SQL injection attack은 사용자가 SQL 문 의도를 변경하는 값을 고의로 입력하는 경우 발생한다.
- preparedStatement.executeQuery() 메서드는 placeholder에 값을 할당할 때 SQL injection attack을 방지한다.
- 사용자가 항공편 데이터를 입력한다.
- flightInsert는 세 개의 ? placeholder를 포함하며, 값은 준비된 문장이 실행될 때 할당된다.
- PreparedStatement 객체는 flightInsert 문자열에 있는 SQL 문으로 생성된다.
- executeUpdate()가 실행되면 Java 값이 placeholder에 할당된다. Java 데이터 타입은 자동으로 MySQL 데이터 타입으로 변환된다.
- close()는 PreparedStatement 객체의 자원을 해제한다.
Stored procedure calls
저장 프로시저는 MySQL 절차적 SQL의 일부로, 데이터베이스에 저장되며 Java와 같은 범용 프로그래밍 언어에서 자주 호출된다.
- IN 매개변수: 저장 프로시저에 데이터를 입력한다.
- OUT 매개변수: 저장 프로시저에서 데이터를 출력한다.
CallableStatement 인터페이스는 PreparedStatement를 확장하며 저장 프로시저를 호출하는 메서드를 제공한다.
- CallableStatement 객체 생성
- Connection 인터페이스의 prepareCall() 메서드를 사용하여 생성된다.
- 저장 프로시저 실행
- CallableStatement의 executeQuery() 메서드로 저장 프로시저를 실행한다.
- 매개변수와 Java 값의 연결
- setInt(): IN 매개변수를 지정된 Java int 값으로 설정한다.
- setString(): IN 매개변수를 지정된 Java String 값으로 설정한다.
- registerOutParameter(): OUT 매개변수를 지정된 JDBC 타입으로 설정한다.
- FlightCount 저장 프로시저는 특정 항공사의 항공편 수를 계산한다.
- prepareCall() 메서드는 CallableStatement 객체를 생성한다.
- setString()은 항공사 매개변수에 값을 바인딩하고, registerOutParameter()는 quantity 매개변수에 값을 바인딩한다. executeQuery()는 저장 프로시저를 실행한다.
- 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
'데이터베이스 시스템' 카테고리의 다른 글
11.1 Entities, relationships, and attributes (0) 2024.11.27 10.4 Database programming with Python (0) 2024.11.25 10.3 MySQLi (PHP) (0) 2024.11.24 10.2 Database programming for the web (0) 2024.11.23 10.1 Application programming interfaces (0) 2024.11.22