6.1 行集介绍

如您所知,JDBC 标准已有将近 20 年的历史,而且有点过时了。新的类型和新的类正在慢慢地加入其中,但这并不是处处都能做得漂亮的。其中一个地方是ResultSet

数据库可以变得更高效,但ResultSet接口不太合适。此外,我们没有在任何地方显式创建它的对象,它们由executeQuery().

JDBC 的创建者没有考虑很久,就创造了一种与以前的一切完全平行的机制。它被称为RowSet

以下是它的主要优点:

  • RowSet 扩展了ResultSet 接口,因此其功能比ResultSet 更强大。
  • RowSet 可以更灵活地浏览表格数据,并且可以来回滚动。
  • RowSet 维护即使在连接关闭后也可以使用的缓存数据。
  • RowSet 支持新的连接方式,无需连接即可连接数据库。它还支持读取 XML 数据源。
  • RowSet 支持数据过滤器。
  • RowSet 还支持表连接操作。

行集类型:

  • 缓存行集
  • 过滤行集
  • Jdbc行集
  • 连接行集
  • Web行集

6.2 创建 RowSet 对象

可以通过三种不同的方式获取工作对象。

首先,它可以填充以传统方式获得的ResultSet中的数据。

例如,我们可以使用CachedRowSet缓存ResultSet数据:


Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");
 
RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet crs = factory.createCachedRowSet();
crs.populate(results);		// Use ResultSet to populate

其次,您可以通过为它创建自己的数据库连接来创建一个完全独立的RowSet对象:


JdbcRowSet rowSet = RowSetProvider.newFactory().createJdbcRowSet();
rowSet.setUrl("jdbc:mysql://localhost:3306/test");
rowSet.setUsername("root");
rowSet.setPassword("secret");
 
rowSet.setCommand("SELECT * FROM user");
rowSet.execute();

第三,您可以将 RowSet 连接到一个已经存在的连接:

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
JdbcRowSet rowSet = new JdbcRowSetImpl(con);

rowSet.setCommand("SELECT * FROM user");
rowSet.execute();

6.3 使用 RowSet 的例子

示例一:缓存

让我们编写一段代码,我们使用CachedRowSet来缓存所有数据并从已关闭的连接中读取它:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");

RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet crs = factory.createCachedRowSet();
crs.populate(results);	// Use ResultSet to populate

connection.close();		// Close the connection

// Cache data is still available
while(crs.next()) {
  	System.out.println(crs.getString(1)+"\t"+ crs.getString(2)+"\t"+ crs.getString(3));
}

示例二:通过 RowSet 更改行

// Connect to the database
 CachedRowSet crs = rsf.createCachedRowSet();
 crs.setUrl("jdbc:mysql://localhost/test");
 crs.setUsername("root");
 crs.setPassword("root");
 crs.setCommand("SELECT * FROM user");
 crs.execute();

// This type of operation can only change standalone RowSet
// First, move the pointer to an empty (new) string, the current position is remembered
 crs.moveToInsertRow();
 crs.updateString(1, Random.nextInt());
 crs.updateString(2, "Clone" + System.currentTimeMillis());
 crs.updateString(3, "Female");
 crs.insertRow();  // Add the current (new) line to the rest of the lines
 crs.moveToCurrentRow(); // Return a pointer to the line where it was before insertion

 crs.beforeFirst();
 while(crs.next()) {
 	System.out.println(crs.getString(1) + "," + crs.getString(2) + "," + crs.getString(3));
}

// And now we can upload all our changes to the database
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/dbtest", "root", "root");
con.setAutoCommit(false); // Needed for synchronization
crs.acceptChanges(con);// Synchronize data to database

如果您对它的工作原理感兴趣,可以阅读官方文档中的主题。我现在的任务只是告诉它是什么。