RowSet概念
在C#中,提供了一個DataSet,可以把數據庫的數據放在內存中進行離線操作(讀寫),操作完成之后再同步到數據庫中去,Java中則提供了類似的功能RowSet.
RowSet接口繼承自ResultSet接口。與ResultSet相比,RowSet默認是可滾動、可更新、可序列化的結果集,可以作為JavaBean來方便地在網絡上傳輸,用于同步兩端數據。對于離線RowSet而言,
程序從創建RowSet時就已經把數據load進內存,因此可以更好地利用內存性能,降低數據庫服務器的負載,提高程序性能。
RowSet接口下包含了JdbcRowSet, CachedRowSet, FilteredRowSet, JoinRowSet, WebRowSet,除了JdbcRowSet之外,后面四個都是離線RowSet,它們之間的繼承關系如下,
RowSetFactory
在JDK1.6及以前的版本中,如果要使用JdbcRowSet,則必須使用JdbcRowSetImpl的構造器來構造對象,但是在編譯的時候會有警告,因此JdbcRowSetImpl是內部專用的API,在未來版本可能會刪除。這種獲取JdbcRowSet的方式是不推薦的,因為使用內部API,在將來的版本中可能不兼容,而且這樣的程序直接與具體的實現類JdbcRowSetImpl耦合,不利于維護和升級。
在JDK1.7中,這個問題得到了改善。JDK1.7引入了RowSetFactory和RowSetProvider接口,其中RowSetProvider負責創建RowSetFactory,而RowSetFactory則可以通過以下方法創建RowSet實例,
createCachedRowSet()
createFilteredRowSet()
createJdbcRowSet()
createJoinRowSet()
createWebRowSet()
通過RowSetFactory,程序就可以與RowSet的實現類分離,避免了直接使用具體的實現類JdbcRowSetImpl。
創建對象時可以傳入ResultSet實例填充RowSet,也可以在創建JdbcRowSet實例之后通過execute(sql)方法得到數據填充RowSet,
下面演示使用RowSetFactory和RowSetProvider接口獲取RowSet實例并使用的方法,
1 packagedb;2
3 importjava.io.FileInputStream;4 importjava.io.FileNotFoundException;5 importjava.io.IOException;6 importjava.sql.Connection;7 importjava.sql.DriverManager;8 importjava.sql.SQLException;9 importjava.util.Properties;10
11 importjavax.sql.rowset.JdbcRowSet;12 importjavax.sql.rowset.RowSetFactory;13 importjavax.sql.rowset.RowSetProvider;14
15
16 public classRowSetFactoryTest {17 privateString driver;18 privateString url;19 privateString user;20 privateString pass;21 public void initParam(String paramFile) throwsFileNotFoundException, IOException, ClassNotFoundException {22 //用Properties類加載屬性文件
23 Properties prop = newProperties();24 prop.load(newFileInputStream(paramFile));25 driver = prop.getProperty("driver");26 url = prop.getProperty("url");27 user = prop.getProperty("user");28 pass = prop.getProperty("pass");29 Class.forName(driver);30 }31
32 public void update(String sql) throwsSQLException {33 RowSetFactory factory =RowSetProvider.newFactory();34
35 try(36 //使用RowSet的execute方式返回數據,則不再需DriverManager連接數據庫了37 //Connection conn = DriverManager.getConnection(url, user, pass);
38 /*
39 * for JDK1.640 * JdbcRowSet jdbcRs = new JdbcRowSetImpl(conn);41 */
42 //for JDK 1.7
43 JdbcRowSet jdbcRs =factory.createJdbcRowSet();44 ) {45 jdbcRs.setUrl(url);46 jdbcRs.setUsername(user);47 jdbcRs.setPassword(pass);48 jdbcRs.setCommand(sql);49 jdbcRs.execute();50
51 jdbcRs.afterLast();52 //向前滾動結果集
53 while(jdbcRs.previous()) {54 System.out.println(jdbcRs.getInt(1)+"\t"+jdbcRs.getString(2)+"\t"+jdbcRs.getString(3));55
56 if (jdbcRs.getInt("jdbc_id") == 3) {57 //修改指定行記錄,因為 JdbcRowSet 繼承自 ResultSet, 所以修改記錄的方式也一樣
58 jdbcRs.updateString("jdbc_name", "小明");59 jdbcRs.updateRow();60 System.out.println("修改成功: ");61 System.out.println(+jdbcRs.getInt(1)+"\t"+jdbcRs.getString(2)+"\t"+jdbcRs.getString(3));62 }63
64 }65 }66 }67
68 public static void main(String[] args) throwsFileNotFoundException, ClassNotFoundException, IOException, SQLException {69 RowSetFactoryTest jt = newRowSetFactoryTest();70 jt.initParam("mysql.ini");71 jt.update("select * from jdbc_test");72 }73 }
執行上面程序會發現第3行被修改了,需要注意的是JdbcRowSet并不是離線的RowSet,因此需要在數據庫保持連接的情況下才能修改數據
因為JdbcRowSet接口繼承自ResultSet,所以修改數據的方法跟ResultSet一樣的。 程序執行結果如下,
1 27學生名27 學生名282 26學生名26 學生名273 25學生名25 學生名264 24學生名24 學生名255 23學生名23 學生名246 22學生名22 學生名237 21學生名21 學生名228 20學生名20 學生名219 19學生名19 學生名2010 18學生名18 學生名1911 17學生名17 學生名1812 16學生名16 學生名1713 15學生名15 學生名1614 14學生名14 學生名1515 13學生名13 學生名1416 12學生名12 學生名1317 11學生名11 學生名1218 10學生名10 學生名1119 9學生名9 學生名1020 8學生名8 學生名921 7學生名7 學生名822 6學生名6 學生名723 5學生名5 學生名624 4學生名4 學生名525 3小明 小強26 修改成功:27 3小明 小強28 2學生名2 學生名329 1 學生名1 學生名2
View Code