Javaでデータベース関連の処理を実装する際、SQLの実行結果を格納するために用いられるのが「ResultSet」インターフェースです。
本記事では、JavaのResultSetインターフェースについて、基本的な使い方をサンプルコードを掲載しながらご紹介していきます。
目次
JavaのResultSetインターフェースとは

ResultSetは「java.sql」のパッケージに含まれるインターフェースで、同パッケージに含まれる様々なSQL関連メソッドの実行結果を格納するために利用されます。
ResultSetを返却するメソッド
「java.sql」パッケージの中で、利用されることの多いResultSetを返却するメソッドは「executeQuery」と「getResultSet」です。
- Statement.executeQuery(String sql)
 - Statement.getResultSet()
 
executeQueryメソッド
executeQueryメソッドでは、単一のResultSetオブジェクトを返却するSQL文が実行されます。
ResultSet rs = Statement.executeQuery(String sql);
executeQueryの実行結果を、ResultSetで指定したオブジェクトに格納します。
getResultSetメソッド
getResultSetメソッドでは、オブジェクトとして現在の結果を返却します。
ResultSet rs = Statement.getResultSet();
executeQueryとは違い、引数にSQL文を設定するわけではありません。
発行済のSQL文の結果を取得する際、利用されます。
ResultSetで利用可能なメソッド
ResultSetに格納したデータは、各種メソッドを利用することで操作することが可能です。
ResultSetではカーソルという考え方で、取得したデータを行単位で動かしながら処理を実行していきます。
カーソル移動
- first: 先頭行にカーソルを移動
 - last: 最終行にカーソルを移動
 - next: 次の行にカーソルを移動
 - previous: 前の行にカーソルを移動
 - absolute(行番号): 指定した行にカーソルを移動
 
現在行のデータ取得
- getInt(カラム名): 指定したカラムのデータをint型で取得
 - getString(カラム名): 指定したカラムのデータをString型で取得
 - getBoolean(カラム名): 指定したカラムのデータをBoolean型で取得
 
カーソル状態確認
- isFirst: カーソルが先頭行にあるかどうかの確認
 - isLast: カーソルが最終行にあるかどうかの確認
 - isClosed: ResultSetオブジェクトがクローズされているかどうかの確認
 
ResultSetにexecuteQueryメソッドの問い合わせ結果を格納するサンプル

executeQueryメソッドを利用して、ResultSetにデータを格納してみたいと思います。
今回はサンプルのデータベースとしてMySQLを利用しており、接続方法はJDBCを使用しています。
サンプル用テーブル
サンプル用のデータベース「test_db」に「fruits」テーブルを下記のデータで作成しています。
+------+-----------+ | id | name | +------+-----------+ | 1 | りんご | | 2 | みかん | | 3 | ぶどう | +------+-----------+
サンプルコード
サンプル用の「fruits」テーブルから全データを取得し、コンソールに出力するサンプルコードが下記となります。
package sample;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;
    public static void main(String arg[]) {
    	Connection conn = null;
        try {
            // データベースに接続
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost/test_db", "root", "test1234");
            // ステートメント作成
            Statement stmt = conn.createStatement();
            // SQL文発行
            String sql = "SELECT * FROM fruits";
            ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()) {
            	int id = rs.getInt("id");
            	String name = rs.getString("name");
            	System.out.println("現在行のデータはid=" + id + " name=" + name + "です。");
            }
            
            rs.close();
            stmt.close();
        } catch (Exception e) {
        	System.out.println(e);
        } finally {
            try{
                if (conn != null){
                  conn.close();
                }
            } catch(SQLException e) {
            	System.out.println(e);
            }
        }
    }
}
実行結果
現在行のデータはid=1 name=りんごです。 現在行のデータはid=2 name=みかんです。 現在行のデータはid=3 name=ぶどうです。
サンプルコード解説
簡単にResultSetインターフェースに関連する部分を説明していきたいと思います。
// SQL文発行 String sql = "SELECT * FROM fruits"; ResultSet rs = stmt.executeQuery(sql);
この部分がSQL文を発行し、実際に実行している処理となります。
SQLの実行結果はResultSetのオブジェクトとして定義した「rs」変数に格納されます。
while(rs.next()) {
    int id = rs.getInt("id");
    String name = rs.getString("name");
    System.out.println("現在行のデータはid=" + id + " name=" + name + "です。");
}
取得したResultSetのオブジェクトを操作しているのがこの記述です。
whileで取得データをループさせ、ResultSetが持つ「next()」メソッドにより1行ずつ処理を実施しています。
各行のデータは「getInt()」「getString()」メソッドでカラム名を指定し取得しています。
rs.close(); stmt.close();
最後に使用しなくなったResultSetオブジェクトのカーソル「close()」メソッドでクローズしておくことで、JDBCのリソースを解放しています。
getResultSetメソッドで格納したデータを操作するサンプル

では上記サンプルをもう少し色々なメソッドを利用して操作してみましょう。
サンプルコード
package sample;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;
    public static void main(String arg[]) {
    	Connection conn = null;
        try {
            // データベースに接続
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost/test_db", "root", "test1234");
            // ステートメント作成
            Statement stmt = conn.createStatement();
            // SQL文発行
            stmt.execute("SELECT * FROM fruits");
            // SQL文の実行結果を格納
            ResultSet rs = stmt.getResultSet();
            if(rs.isFirst()) {
            	System.out.println("カーソルは最初の行にあります。");
            } else {
            	System.out.println("カーソルは最初の行にありません。");
            	if(rs.isBeforeFirst()) {
            		System.out.println("カーソルは最初の行の前にあります。");
            	}
            }
            rs.last();
            System.out.println("カーソルを最終行に移動しました。");
            if(rs.isLast()) {
            	int id = rs.getInt("id");
            	String name = rs.getString("name");
            	System.out.println("最終行のデータはid=" + id + " name=" + name + "です。");
            }
            rs.first();
            System.out.println("カーソルを最初の行に移動しました。");
            while(rs.next()) {
            	int id = rs.getInt("id");
            	String name = rs.getString("name");
            	System.out.println("現在行のデータはid=" + id + " name=" + name + "です。");
            }
            rs.close();
            stmt.close();
        } catch (Exception e) {
        	System.out.println(e);
        } finally {
            try{
                if (conn != null){
                  conn.close();
                }
            } catch(SQLException e) {
            	System.out.println(e);
            }
        }
    }
}
実行結果
カーソルは最初の行にありません。 カーソルは最初の行の前にあります。 カーソルを最終行に移動しました。 最終行のデータはid=3 name=ぶどうです。 カーソルを最初の行に移動しました。 現在行のデータはid=2 name=みかんです。 現在行のデータはid=3 name=ぶどうです。
サンプルコードの違いを確認
executeQueryメソッドを利用した場合との違いはお気づき頂けたでしょうか?
executeQueryでは引数としてSQL文を渡すのに対し、getResultSetでは発行済のSQL文をStatementオブジェクトから取得する違いがあります。
// SQL文発行
stmt.execute("SELECT * FROM fruits");
// SQL文の実行結果を格納
ResultSet rs = stmt.getResultSet();
ResultSetオブジェクトに格納したあとの操作方法は同じです。
if(rs.isFirst()) {
    System.out.println("カーソルは最初の行にあります。");
} else {
    System.out.println("カーソルは最初の行にありません。");
    if(rs.isBeforeFirst()) {
        System.out.println("カーソルは最初の行の前にあります。");
    }
}
rs.last();
System.out.println("カーソルを最終行に移動しました。");
if(rs.isLast()) {
    int id = rs.getInt("id");
    String name = rs.getString("name");
    System.out.println("最終行のデータはid=" + id + " name=" + name + "です。");
}
rs.first();
System.out.println("カーソルを最初の行に移動しました。");
今回のサンプルではループ処理を実行する前にカーソル操作をいくつか実行しています。
注目してもらいたいのはResultSetオブジェクトを作成したタイミングでは、カーソルは最初の行ではなく最初の行の1つ前に設定されていることです。
そのため、「first()」メソッドで最初の行にカーソルを移動しループ処理を実行した結果、「next()」メソッドがまず実行されることになるため、2行目以降のデータから出力される結果となることを意識しておきましょう。
さいごに: ResultSetインターフェースを使用してJavaでデータを操作してみよう

本記事では、ResultSetインターフェースを使用したJavaのデータ操作についてご紹介してきました。
データベースから取得したデータをJava側のプログラムで操作する機会は少なくありません。
頻繁に利用するResultSetのメソッドは限られていますので、少しずつ実際に触ってみながら使い方を覚えていくようにしましょう。
              
    
    
    
    
  
      
    
  
      
詳しい使い方については後ほどサンプルコードを掲載しています。