웹사이트 검색

Java ResultSet 자습서


Java ResultSet 인터페이스는 java.sql 패키지의 일부입니다. JDBC Framework의 핵심 구성 요소 중 하나입니다. ResultSet 개체는 관계형 데이터베이스에서 검색된 쿼리 결과에 액세스하는 데 사용됩니다.

ResultSet은 쿼리 결과의 단일 행을 가리키는 커서/포인터를 유지합니다. ResultSet에서 제공하는 탐색 및 getter 메서드를 사용하여 데이터베이스 레코드를 하나씩 반복하고 액세스할 수 있습니다. ResultSet을 사용하여 데이터를 업데이트할 수도 있습니다.

Java ResultSet 계층 구조

위의 다이어그램은 JDBC 프레임워크에서 ResultSet의 위치를 보여줍니다. ResultSet은 Statement, PreparedStatement 또는 CallableStatement를 사용하여 SQL 쿼리를 실행하여 얻을 수 있습니다.

AutoCloseable, Wrapper는 ResultSet의 상위 인터페이스입니다. 이제 Java 프로그램에서 ResultSet으로 작업하는 방법을 살펴보겠습니다.

결과 집합 예

예제 목적으로 MySQL을 사용할 것입니다. 아래 DB 스크립트를 사용하여 일부 레코드와 함께 데이터베이스 및 테이블을 생성하십시오.

create database empdb;

use empdb;

create table tblemployee (empid integer primary key, firstname varchar(32), lastname varchar(32), dob date);

insert into tblemployee values  (1, 'Mike', 'Davis',' 1998-11-11');
insert into tblemployee values  (2, 'Josh', 'Martin', '1988-10-22');
insert into tblemployee values  (3, 'Ricky', 'Smith', '1999-05-11');

테이블에서 레코드를 가져와 콘솔에 출력하는 아래 예제 프로그램을 살펴보겠습니다. 프로젝트 클래스 경로에 MySQL JDBC 드라이버가 있는지 확인하십시오.

package com.journaldev.examples;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Date;

/**
 * Java Resultset Example of Retrieving records.
 * 
 * @author pankaj
 *
 */

public class ResultSetDemo {

	public static void main(String[] args) {
		String query = "select empid, firstname, lastname, dob from tblemployee";
		Connection conn = null;
		Statement stmt = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/empdb", "root", "root");
			stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(query);
			while (rs.next()) {
				Integer empId = rs.getInt(1);
				String firstName = rs.getString(2);
				String lastName = rs.getString(3);
				Date dob = rs.getDate(4);
				System.out.println("empId:" + empId);
				System.out.println("firstName:" + firstName);
				System.out.println("lastName:" + lastName);
				System.out.println("dob:" + dob);
				System.out.println("");
			}
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				stmt.close();
				conn.close();
			} catch (Exception e) {}
		}
	}
}

산출:

empId:1
firstName:Mike
lastName:Davis
dob:1998-11-11

empId:2
firstName:Josh
lastName:Martin
dob:1988-10-22

empId:3
firstName:Ricky
lastName:Smith
dob:1999-05-11

설명:

  • ResultSet은 Statement 인스턴스에서 executeQuery 메서드를 호출하여 얻습니다. 처음에 ResultSet의 커서는 첫 번째 행 앞의 위치를 가리킵니다.
  • ResultSet의 next 메서드는 커서를 다음 행으로 이동합니다. 추가 행이 있으면 true를 반환하고 그렇지 않으면 false를 반환합니다.
  • 우리는 ResultSet에서 제공하는 getter 메소드를 사용하여 ResultSet에서 데이터를 얻을 수 있습니다. 예를 들어 getInt(), getString(), getDate()
  • 모든 getter 메서드에는 두 가지 변형이 있습니다. 첫 번째 변형은 열 인덱스를 매개변수로 사용하고 두 번째 변형은 열 이름을 매개변수로 사용합니다.
  • 마지막으로 모든 리소스가 제대로 정리되도록 ResultSet 인스턴스에서 close 메서드를 호출해야 합니다.

ResultSet 유형 및 동시성

Statement, CallableStatement의 인스턴스를 생성하면서 ResultSet의 유형과 동시성을 지정할 수 있습니다.

statement.createStatement(int resultSetType, int resultSetConcurrency)

결과 집합 유형

1) 전달 전용(ResultSet.TYPE_FORWARD_ONLY)

이 유형의 ResultSet 인스턴스는 첫 번째 행에서 마지막 행으로 정방향으로만 이동할 수 있습니다. ResultSet은 next() 메소드를 호출하여 한 행 앞으로 이동할 수 있습니다. Statement, PreparedStatement 또는 CallableStatement의 인스턴스를 생성하는 동안 이러한 유형의 ResultSet을 얻을 수 있습니다.

Statement stmt = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("select * from tbluser");

2) 스크롤 둔감(ResultSet.TYPE_SCROLL_INSENSITIVE)

Scroll Insensitive ResultSet는 앞뒤 방향 모두로 스크롤할 수 있습니다. absolute() 메서드를 호출하여 절대 위치로 스크롤할 수도 있습니다. 그러나 데이터 변경에 민감하지 않습니다. 쿼리가 실행되고 ResultSet을 얻은 경우에만 데이터가 있습니다. 데이터를 가져온 후 변경된 데이터는 반영되지 않습니다.

Statement stmt = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,  		ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("select * from tbluser");

3) 스크롤 민감(ResultSet.TYPE_SCROLL_SENSITIVE)

Scroll Sensitive ResultSet는 앞뒤 방향 모두로 스크롤할 수 있습니다. absolute() 메서드를 호출하여 절대 위치로 스크롤할 수도 있습니다. 그러나 데이터 변경에 민감합니다. 열려 있는 동안 데이터에 대한 변경 사항을 반영합니다.

Statement stmt = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,  		ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("select * from tbluser");

ResultSet 동시성

1) 읽기 전용(ResultSet.CONCUR_READ_ONLY)

기본 동시성 모델입니다. ResultSet 인스턴스에서는 읽기 전용 작업만 수행할 수 있습니다. 업데이트 작업이 허용되지 않습니다.

2) 업데이트 가능(ResultSet.CONCUR_UPDATABLE)

이 경우 ResultSet 인스턴스에 대한 업데이트 작업을 수행할 수 있습니다.

ResultSet 메서드

ResultSet 메서드를 다음 범주로 나눌 수 있습니다.

  • 탐색 방법
  • Getter/Reader 메서드
  • 세터/업데이터 방법
  • 기타 메소드 - close() 및 getMetaData()

1. ResultSet 탐색 방법

  • boolean absolute(int row) throws SQLException**:** 이 메서드는 ResultSet 커서를 지정된 행으로 이동하고 작업이 성공하면 true를 반환합니다.
  • void afterLast() throws SQLException**:** 이 메서드는 ResultSet 커서를 마지막 행 이후 위치로 이동합니다.
  • void beforeFirst() throws SQLException**:** 이 메서드는 ResultSet 커서를 첫 번째 행 앞의 위치로 이동합니다.
  • boolean first() throws SQLException: 이 메서드는 ResultSet 커서를 첫 번째 행으로 이동합니다.
  • boolean last() throws SQLException: 이 메서드는 ResultSet 커서를 마지막 행으로 이동합니다.
  • 부울 next()에서 SQLException 발생: 이 메서드는 ResultSet 커서를 다음 행으로 이동합니다.
  • boolean previous() throws SQLException: 이 메서드는 ResultSet 커서를 이전 행으로 이동합니다.

package com.journaldev.examples;
import java.sql.*;

/**
 * Java Resultset Example using navigational methods.
 * 
 * @author pankaj
 *
 */
public class ResultSetDemo {

	public static void main(String[] args) {
		String query = "select empid, firstname, lastname, dob from tblemployee";
		Connection conn = null;
		Statement stmt = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/empdb", "root", "root");
			stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
			ResultSet rs = stmt.executeQuery(query);
			System.out.println("All the rows of table=>");
			while (rs.next()) { 
				// Go to next row by calling next() method
				displayData(rs);
			}
			System.out.println("Now go directly to 2nd row=>");
			rs.absolute(2); // Go directly to 2nd row
			displayData(rs);
			System.out.println("Now go to Previous row=>");
			rs.previous(); 
			// Go to 1st row which is previous of 2nd row
			displayData(rs);
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				stmt.close();
				conn.close();
			} catch (Exception e) {
			}
		}
	}

	public static void displayData(ResultSet rs) throws SQLException {
		System.out.println("empId:" + rs.getInt(1));
		System.out.println("firstName:" + rs.getString(2));
		System.out.println("lastName:" + rs.getString(3));
		System.out.println("dob:" + rs.getDate(4));
		System.out.println("");
	}
}

산출:

All the rows of table=>
empId:1
firstName:Mike
lastName:Davis
dob:1998-11-11

empId:2
firstName:Josh
lastName:Martin
dob:1988-10-22

empId:3
firstName:Ricky
lastName:Smith
dob:1999-05-11

Now go directly to 2nd row=>
empId:2
firstName:Josh
lastName:Martin
dob:1988-10-22

Now go to Previous row=>
empId:1
firstName:Mike
lastName:Davis
dob:1998-11-11

2. ResultSet Getter/Reader 메소드

  • int getInt(int columnIndex) throws SQLException: 이 메서드는 지정된 columnIndex의 값을 int로 반환합니다.
  • long getLong(int columnIndex) throws SQLException: 이 메서드는 지정된 columnIndex의 값을 long으로 반환합니다.
  • String getString(int columnIndex) throws SQLException: 이 메서드는 지정된 columnIndex의 값을 문자열로 반환합니다.
  • java.sql.Date getDate(int columnIndex) throws SQLException: 이 메서드는 지정된 columnIndex의 값을 java.sql.Date로 반환합니다.
  • int getInt(String columnLabel) throws SQLException: 이 메서드는 지정된 열 이름의 값을 int로 반환합니다.
  • long getLong(String columnLabel) throws SQLException: 이 메서드는 지정된 열 이름의 값을 long으로 반환합니다.
  • String getString(String columnLabel) throws SQLException: 이 메서드는 지정된 열 이름의 값을 문자열로 반환합니다.
  • java.sql.Date getDate(String columnLabel) throws SQLException: 이 메서드는 지정된 열 이름의 값을 java.sql.Date로 반환합니다.
  • ResultSet에는 boolean, float 및 double과 같은 다른 기본 데이터 유형을 반환하는 getter 메서드가 포함되어 있습니다. 또한 데이터베이스에서 배열 및 이진 데이터를 가져오는 방법도 있습니다.

3. ResultSet Setter/Updater 메소드

  • void updateInt(int columnIndex, int x) throws SQLException: 이 메서드는 현재 행의 지정된 열 값을 int 값으로 업데이트합니다.
  • void updateLong(int columnIndex, long x) throws SQLException: 이 메서드는 현재 행의 지정된 열 값을 long 값으로 업데이트합니다.
  • void updateString(int columnIndex, String x) throws SQLException: 이 메서드는 현재 행의 지정된 열 값을 문자열 값으로 업데이트합니다.
  • void updateDate(int columnIndex, java.sql.Date x) throws SQLException: 이 메서드는 현재 행의 지정된 열 값을 java.sql.Date 값으로 업데이트합니다.
  • void updateInt(String columnLabel, int x) throws SQLException: 이 메서드는 현재 행의 지정된 열 레이블 값을 int 값으로 업데이트합니다.
  • void updateLong(String columnLabel, long x) throws SQLException: 이 메서드는 현재 행의 지정된 열 레이블 값을 long 값으로 업데이트합니다.
  • void updateString(String columnLabel, String x) throws SQLException: 이 메서드는 현재 행의 지정된 열 레이블 값을 문자열 값으로 업데이트합니다.
  • void updateDate(String columnLabel, java.sql.Date x) throws SQLException: 이 메서드는 현재 행의 지정된 columnLabel 값을 java.sql.Date 값으로 업데이트합니다.

참고: Setter/Updater 메서드는 데이터베이스 값을 직접 업데이트하지 않습니다. 데이터베이스 값은 insertRow 또는 updateRow 메서드를 호출한 후 삽입/업데이트됩니다.

package com.journaldev.examples;
import java.sql.*;

/**
 * Java Resultset Example using updater methods.
 * 
 * @author pankaj
 *
 */

public class ResultSetUpdateDemo {

	public static void main(String[] args) {
		String query = "select empid, firstname, lastname, dob from tblemployee";
		Connection conn = null;
		Statement stmt = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/empdb", "root", "root");
			stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
			ResultSet rs = stmt.executeQuery(query);
			System.out.println("Now go directly to 2nd row for Update");
			if (rs.absolute(2)) { 
				// Go directly to 2nd row
				System.out.println("Existing Name:" + rs.getString("firstName"));
				rs.updateString("firstname", "Tyson");
				rs.updateRow();
			}
			rs.beforeFirst(); // go to start
			System.out.println("All the rows of table=>");
			while (rs.next()) { 
			// Go to next row by calling next() method
				displayData(rs);
			}
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				stmt.close();
				conn.close();
			} catch (Exception e) {
			}
		}
	}

	public static void displayData(ResultSet rs) throws SQLException {
		System.out.println("empId:" + rs.getInt(1));
		System.out.println("firstName:" + rs.getString(2));
		System.out.println("lastName:" + rs.getString(3));
		System.out.println("dob:" + rs.getDate(4));
		System.out.println("");
	}
}

산출:

Now go directly to 2nd row for Update
Existing Name:Josh
All the rows of table=>
empId:1
firstName:Mike
lastName:Davis
dob:1998-11-11

empId:2
firstName:Tyson
lastName:Martin
dob:1988-10-22

empId:3
firstName:Ricky
lastName:Smith
dob:1999-05-11

4. ResultSet 기타 메소드

  • void close() throws SQLException**:** 이 메서드는 ResultSet 인스턴스와 관련된 리소스를 해제합니다. 호출해야 합니다. 그렇지 않으면 리소스가 누출될 수 있습니다.
  • ResultSetMetaData getMetaData()가 SQLException을 발생시킵니다. 이 메서드는 ResultSetMetaData 인스턴스를 반환합니다. 쿼리 출력의 열 유형 및 속성에 대한 정보를 제공합니다.

참조: 자바 문서