結果セットのデータ サンプルのキャッシング
この SQL Server 用 Microsoft JDBC ドライバー サンプル アプリケーションは、 データベースから大きなデータのセットを取得表示する方法を示しています。 その後に、SQLServerResultSet オブジェクトの setFetchSize メソッドを使用することによりクライアント上でキャッシュされるデータの行数を制御します。
Note
クライアント上でキャッシュされる行数の制限は、結果セットが含むことのできる行の総数の制限とは異なります。 結果セットに含まれる行の総数を制御するには、SQLServerStatement オブジェクトの setMaxRows メソッドを使用します。これは、SQLServerPreparedStatement オブジェクトと SQLServerCallableStatement オブジェクトの両方に継承されます。
クライアントでキャッシュされる行数に制限を設けるには、Statement オブジェクトの作成時にサーバー側カーソルを使用するカーソルの種類を指定します。 たとえば、JDBC ドライバーでは TYPE_SS_SERVER_CURSOR_FORWARD_ONLY というカーソルの種類が提供されます。これは、SQL Server データベースで使用する高速順方向専用、読み取り専用のサーバー側カーソルです。
Note
SQL Server 固有のカーソルの種類を使用する代わりに、selectMethod 接続文字列プロパティの値を "cursor" に設定して使用する方法もあります。 JDBC ドライバーでサポートされるカーソルの種類の詳細については、「カーソルの種類について」を参照してください。
Statement オブジェクト内のクエリを実行し、データが結果セットとしてクライアントに返されたら、setFetchSize
メソッドを呼び出して、データベースから一度に取得されるデータの量を制御します。 たとえば、100 行のデータを持つテーブルがあり、フェッチ サイズが 10 の場合、クライアント上で一度にキャッシュされるのは 10 行のデータだけです。 この設定により、データの処理速度が遅くなることがありますが、クライアントでのメモリ使用量は少なくなります。 このシナリオは、メモリをあまり使わずに大量のデータを処理する必要がある場合に便利です。
このサンプルのコード ファイルは CacheResultSet.java という名前で、次の場所にあります。
\<installation directory>\sqljdbc_<version>\<language>\samples\resultsets
要件
このサンプル アプリケーションを実行するには、クラスパスを設定して mssql-jdbc jar ファイルを含めます。 また、AdventureWorks2022 サンプル データベースへのアクセス権も必要です。 クラスパスを設定する方法の詳細については、「JDBC ドライバーの使用」を参照してください。
注意
SQL Server 用 Microsoft JDBC ドライバー には、必要な Java ランタイム環境 (JRE) 設定に応じて使用される mssql-jdbc クラス ライブラリ ファイルが用意されています。 選択する JAR ファイルの詳細については、「JDBC Driver のシステム要件」を参照してください。
例
次の例のサンプル コードでは、AdventureWorks2022 サンプル データベースへの接続を行います。 次に、SQLServerStatement オブジェクトで SQL ステートメントを使用し、サーバー側のカーソルの種類を指定し、SQL ステートメントを実行します。 データは SQLServerResultSet オブジェクトで返されます。
次に、サンプル コードはカスタム timerTest メソッドを呼び出し、使用するフェッチ サイズと結果セットを引数として渡します。 timerTest メソッドは、setFetchSize メソッドを使用して結果セットのフェッチ サイズを設定し、テストの開始時刻を設定し、While
ループを使用して結果セットを繰り返し処理します。 While
ループが終了したら、コードはテストの停止時刻を設定し、フェッチ サイズ、処理された行数、テストの実行にかかった時間など、テストの結果を表示します。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import com.microsoft.sqlserver.jdbc.SQLServerResultSet;
public class CacheResultSet {
@SuppressWarnings("serial")
public static void main(String[] args) {
// Create a variable for the connection string.
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=AdventureWorks;user=<user>;password=<password>";
try (Connection con = DriverManager.getConnection(connectionUrl);
Statement stmt = con.createStatement(SQLServerResultSet.TYPE_SS_SERVER_CURSOR_FORWARD_ONLY, SQLServerResultSet.CONCUR_READ_ONLY);) {
String SQL = "SELECT * FROM Sales.SalesOrderDetail;";
for (int n : new ArrayList<Integer>() {
{
add(1);
add(10);
add(100);
add(1000);
add(0);
}
}) {
// Perform a fetch for every nth row in the result set.
try (ResultSet rs = stmt.executeQuery(SQL)) {
timerTest(n, rs);
}
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
private static void timerTest(int fetchSize,
ResultSet rs) throws SQLException {
// Declare the variables for tracking the row count and elapsed time.
int rowCount = 0;
long startTime = 0;
long stopTime = 0;
long runTime = 0;
// Set the fetch size then iterate through the result set to
// cache the data locally.
rs.setFetchSize(fetchSize);
startTime = System.currentTimeMillis();
while (rs.next()) {
rowCount++;
}
stopTime = System.currentTimeMillis();
runTime = stopTime - startTime;
// Display the results of the timer test.
System.out.println("FETCH SIZE: " + rs.getFetchSize());
System.out.println("ROWS PROCESSED: " + rowCount);
System.out.println("TIME TO EXECUTE: " + runTime);
System.out.println();
}
}