JDBC에서 ResultSet(결과 집합)은 데이터베이스 쿼리 결과를 담는 객체로, 커서(cursor)의 이동 방식에 따라 크게 두 가지 유형으로 나뉩니다. 바로 순방향 전용(Forward Only) ResultSet과 양방향(Bidirectional) ResultSet입니다.
1. 순방향 전용(Forward Only) ResultSet
커서가 한 방향(앞쪽)으로만 이동하는 ResultSet 객체를 순방향 전용 ResultSet이라고 합니다. JDBC에서 결과 집합은 기본적으로 순방향 전용 타입으로 설정되어 있습니다.
순방향 전용 ResultSet의 커서는 ResultSet 인터페이스의 next() 메서드를 사용해 이동할 수 있습니다. 이 메서드는 현재 위치에서 다음 행으로 포인터를 옮기며, boolean 값을 반환합니다. 다음에 읽을 행이 없으면 false를, 행이 존재하면 true를 반환합니다.
따라서 while 루프와 함께 이 메서드를 사용하면 ResultSet 객체의 내용을 손쉽게 반복 처리할 수 있습니다.
while(rs.next()){
}예제
다음과 같은 데이터가 들어 있는 dataset 테이블이 있다고 가정해 보겠습니다.
+--------------+-----------+ | mobile_brand | unit_sale | +--------------+-----------+ | Iphone | 3000 | | Samsung | 4000 | | Nokia | 5000 | | Vivo | 1500 | +--------------+-----------+
아래 예제는 Dataset 테이블의 모든 레코드를 조회하고 결과를 출력합니다.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class RetrievingData {
public static void main(String args[]) throws Exception {
// 드라이버 등록
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 연결 생성
String mysqlUrl = "jdbc:mysql://localhost/TestDB";
Connection con = DriverManager.getConnection(mysqlUrl, "root", "password");
System.out.println("Connection established......");
// Statement 객체 생성
Statement stmt = con.createStatement();
// 데이터 조회
ResultSet rs = stmt.executeQuery("select * from Dataset");
System.out.println("Contents of the table");
while(rs.next()) {
System.out.print("Brand: "+rs.getString("Mobile_Brand")+", ");
System.out.print("Sale: "+rs.getString("Unit_Sale"));
System.out.println("");
}
}
}실행 결과
Connection established...... Contents of the table Brand: Iphone, Sale: 3000 Brand: Samsung, Sale: 4000 Brand: Nokia, Sale: 5000 Brand: Vivo, Sale: 1500
2. 양방향(Bidirectional) ResultSet
양방향 ResultSet 객체는 커서가 앞뒤 양방향으로 모두 이동할 수 있는 결과 집합입니다.
Connection 인터페이스의 createStatement() 메서드에는 결과 집합 타입(result set type)과 동시성 타입(concurrency type)을 나타내는 두 개의 정수값을 매개변수로 받는 변형 메서드가 있습니다.
Statement createStatement(int resultSetType, int resultSetConcurrency)
양방향 결과 집합을 생성하려면 타입으로 ResultSet.TYPE_SCROLL_SENSITIVE 또는 ResultSet.TYPE_SCROLL_INSENSITIVE를 지정하고, 여기에 동시성 옵션을 함께 전달하면 됩니다.
// Statement 객체 생성 Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
예제
다음 예제는 양방향 ResultSet을 생성하는 방법을 보여줍니다. 여기서는 dataset 테이블에서 데이터를 가져오는 양방향 ResultSet 객체를 만들고, previous() 메서드를 사용해 마지막 행부터 첫 번째 행까지 역순으로 출력합니다.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class BidirectionalResultSet {
public static void main(String args[]) throws Exception {
// 드라이버 등록
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 연결 생성
String mysqlUrl = "jdbc:mysql://localhost/TestDB";
Connection con = DriverManager.getConnection(mysqlUrl, "root", "password");
System.out.println("Connection established......");
// 양방향 스크롤 가능한 Statement 객체 생성
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
// 데이터 조회
ResultSet rs = stmt.executeQuery("select * from Dataset");
rs.afterLast();
System.out.println("Contents of the table");
while(rs.previous()) {
System.out.print("Brand: "+rs.getString("Mobile_Brand")+", ");
System.out.print("Sale: "+rs.getString("Unit_Sale"));
System.out.println("");
}
}
}실행 결과
Connection established...... Contents of the table Brand: Vivo, Sale: 1500 Brand: Nokia, Sale: 5000 Brand: Samsung, Sale: 4000 Brand: IPhone, Sale: 3000
정리
JDBC의 ResultSet은 커서 이동 방식에 따라 순방향 전용과 양방향 두 가지로 구분됩니다. 기본값인 순방향 전용 ResultSet은 next() 메서드로 앞쪽으로만 순회하며, 양방향 ResultSet은 createStatement(int resultSetType, int resultSetConcurrency) 메서드에 스크롤 타입을 지정하여 생성한 뒤 previous(), afterLast() 등의 메서드로 자유롭게 앞뒤 이동이 가능합니다. 데이터 조회 패턴에 맞는 적절한 ResultSet 유형을 선택하면 더욱 효율적인 데이터베이스 프로그래밍이 가능합니다.