缓存结果集数据的示例

下载 JDBC 驱动程序

此 Microsoft JDBC Driver for SQL Server 示例应用程序说明了如何从数据库中检索大量数据。 然后,它通过使用 SQLServerResultSet 对象的 setFetchSize 方法来控制客户端上缓存的数据行数。

注意

限制客户端中缓存的行数与限制结果集中包含的总行数不同。 要控制结果集中包含的总行数,请使用 SQLServerStatement 对象的 setMaxRows 方法,该对象具有继承对象 SQLServerPreparedStatementSQLServerCallableStatement 对象。

若要设置缓存在客户端上的行数限制,请指定在创建 Statement 对象时使用服务器端游标的游标类型。 例如,JDBC 驱动程序提供了 TYPE_SS_SERVER_CURSOR_FORWARD_ONLY 游标类型,该类型是用于 SQL Server 数据库的快速只进、只读的服务器端游标。

注意

如果不使用 SQL Server 的特定游标类型,也可以使用 selectMethod 连接字符串属性,并将其值设置为“cursor”。 有关 JDBC 驱动程序支持的游标类型的详细信息,请参阅了解游标类型

运行完 Statement 对象中的查询且数据已经以结果集的形式返回到客户端后,请调用 setFetchSize 来控制一次从数据库中检索的数据量。 例如,某表格包含 100 行数据,提取大小为 10,则客户端中一次仅缓存 10 行数据。 尽管此设置会降低数据处理速度,但其在客户端上占用的内存较少。 当你需要处理大量数据而不使用过多内存时,此方案非常有用。

此示例的代码文件名为“CacheResultSet.java”,位于以下位置:

\<installation directory>\sqljdbc_<version>\<language>\samples\resultsets

要求

若要运行此示例应用程序,请设置 classpath 以包含 mssql-jdbc jar 文件。 还需要访问 AdventureWorks2022 示例数据库。 若要详细了解如何设置类路径,请参阅使用 JDBC 驱动程序

注意

Microsoft JDBC Driver for SQL Server 提供要使用的 mssql-jdbc 类库文件,具体使用哪个文件取决于首选的 Java Runtime Environment (JRE) 设置。 有关选择哪个 JAR 文件的详细信息,请参阅 JDBC 驱动程序的系统要求

示例

在下面的示例中,示例代码建立与 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();
    }
}

另请参阅

处理结果集