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

如果您對它的工作原理感興趣,可以閱讀官方文檔中的主題。我現在的任務只是告訴它是什麼。