13.6.3 离线RowSe的查询分页

13.6.3 离线RowSet的查询分页

由于CachedRowSet会将数据记录直接装载到内存中,因此如果SQL查询返回的记录过大CachedRowSet将会占用大量的内存,在某些极端的情况下,它甚至会直接导致内存溢出。
为了解决该问题, CachedRowSet提供了分页功能。所谓分页功能就是一次只装载Resultset里的某几条记录,这样就可以避免CachedRowSet占用内存过大的问题。
CachedSet提供了如下方法来控制分页。

方法 描述
populate(Resultset rs, int startRow) 使用给定的Resultset装填RowSet,从Resultset的第startRow条记录开始装填。
setPageSize(int pageSize) 设置CachedRowSet每次返回多少条记录。
previousPage() 在底层Resultset可用的情况下,让CachedSet读取上一页记录。
nextPage() 在底层Resultset可用的情况下,让CachedRowSet读取下一页记录。

下面程序示范了CachedRowSet的分页支持。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import java.util.*;
import java.io.*;
import java.sql.*;
import javax.sql.*;
import javax.sql.rowset.*;

public class CachedRowSetPage
{
private String driver;
private String url;
private String user;
private String pass;
public void initParam(String paramFile) throws Exception
{
// 使用Properties类来加载属性文件
Properties props = new Properties();
props.load(new FileInputStream(paramFile));
driver = props.getProperty("driver");
url = props.getProperty("url");
user = props.getProperty("user");
pass = props.getProperty("pass");
}

public CachedRowSet query(String sql, int pageSize, int page)
throws Exception
{
// 1.加载驱动
Class.forName(driver);
try (
// 2.获取数据库连接
Connection conn = DriverManager.getConnection(url, user, pass);
// 3.创建Statement对象
Statement stmt = conn.createStatement();
// 4.使用Statement对象执行SQL语句
ResultSet rs = stmt.executeQuery(sql))
{
// 使用RowSetProvider创建RowSetFactory
RowSetFactory factory = RowSetProvider.newFactory();
// 创建默认的CachedRowSet实例
CachedRowSet cachedRs = factory.createCachedRowSet();
// 设置每页显示pageSize条记录
cachedRs.setPageSize(pageSize);
// 使用ResultSet装填RowSet,设置从第几条记录开始
cachedRs.populate(rs, (page - 1) * pageSize + 1);
return cachedRs;
}
}
public static void main(String[] args) throws Exception
{
CachedRowSetPage cp = new CachedRowSetPage();
cp.initParam("mysql.ini");
CachedRowSet rs = cp.query("select * from student_table", 3, 2); // ①
// 向后滚动结果集
while (rs.next())
{
System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t"
+ rs.getString(3));
}
}
}

CachedRowSet实现分页的关键代码如下:

1
2
3
4
// 设置每页显示pageSize条记录
cachedRs.setPageSize(pageSize);
// 使用ResultSet装填RowSet,设置从第几条记录开始
cachedRs.populate(rs, (page - 1) * pageSize + 1);

程序中①号代码显示要査询第2页的记录,每页显示3条记录。运行上面程序,可以看到程序只会显示从第4行到第6行的记录,这就实现了分页。