功能:

  1. 添加了JavaBeans组件支持
  2. 让JDBC使用起来更加简单,操作更加丰富

 

知识点摘要:

  1. RowSet继承自ResultSet,添加了JavaBeans组件支持
  2. 5个子接口:(具体见扩展阅读) 
    JdbcRowSet
    CachedRowSet
    WebRowSet
    JoinRowSet
    FilteredRowSet
  3. 优点: 
    1.某些子接口支持离线操作(可断开数据库连接) 
    2.可当作JavaBeans使用,可序列化(方便网络传输)

 

本文摘要:

  1. java7前RowSet的使用(比常规的5步使用jdbc简单很多)
  2. java7后RowSet的使用(更简单)
  3. 演示离线的RowSet
  4. 离线的RowSet操作
  5. RowSet的分页

 

说明:

  1. Java使用DatabaseMetaData来获取数据库相关信息
  2. 本文为了代码结构清晰 采用的是try-with-resource结构,请在java7下使用(或者自己改成传统模式)
  3. 想了解更多请看:官方RowSet使用说明(2013-03-03有效)

 

部分API:

返回类型方法名称说明
StringgetDatabaseProductName()获得数据库产品的名称
StringgetDatabaseProductVersion()获得数据库产品的版本
StringgetDriverVersion()获得JDBC驱动的版本号
StringgetURL()获得当前数据连接的URL
booleanisReadOnly()当前数据连接的数据库是否是只读模式
booleansupportsBatchUpdates()数据库是否支持批量操作
booleansupportsResultSetType(int type)数据库是否支持给定结果集类型
ResultSetgetTables(String catalog,
String schemaPattern,
String tableNamePattern,
String[] types)
简单的讲就是获得数据表的相关信息
ResultSetgetPrimaryKeys(String catalog,
String schema,
String table)
获得某表的主键
ResultSetgetColumns(String catalog,
String schemaPattern,
String tableNamePattern,
String columnNamePattern)
获得某表字段信息

 

程序演示: 放大

  1. package com.cxy.jdbc;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.DriverManager;  
  5. import java.sql.PreparedStatement;  
  6. import java.sql.ResultSet;  
  7. import java.util.UUID;  
  8.   
  9. import javax.sql.rowset.CachedRowSet;  
  10. import javax.sql.rowset.JdbcRowSet;  
  11. import javax.sql.rowset.RowSetFactory;  
  12. import javax.sql.rowset.RowSetProvider;  
  13.   
  14. import com.sun.rowset.JdbcRowSetImpl;  
  15.   
  16. /** 
  17.  * @author cxy @ www.cxyapi.com 
  18.  */  
  19. public class RowSetTest  
  20. {  
  21.     public static void main(String[] args) throws Exception  
  22.     {  
  23.         Class.forName("com.mysql.jdbc.Driver");  
  24.         //java7前的使用方法,是不是看起来简单很多~  
  25.         try  
  26.         (  
  27.                 Connection con=DriverManager.getConnection("jdbc:mysql://localhost/dbtest""root""root");  
  28.                 JdbcRowSet jrs=new JdbcRowSetImpl(con);  //传递一个con给JdbcRowSet构造器就可以啦  
  29.         )  
  30.         {  
  31.             jrs.setCommand("select * from t_student");  
  32.             jrs.execute();  
  33.             System.out.println("id\t姓名\t 性别");  
  34.             while(jrs.next())  
  35.             {  
  36.                 System.out.println(jrs.getString(1)+"\t"+jrs.getString(2)+"\t"+jrs.getString(3));  
  37.             }  
  38.         }  
  39.         System.out.println("=======================");  
  40.           
  41.         //java7开始 提供了RowSetFactory接口来生成各种RowSet  
  42.         RowSetFactory rsf=RowSetProvider.newFactory();  
  43.         try  
  44.         (  
  45.                 JdbcRowSet jrs=rsf.createJdbcRowSet();  
  46.         )  
  47.         {  
  48.             jrs.setUrl("jdbc:mysql://localhost/dbtest");  
  49.             jrs.setUsername("root");  
  50.             jrs.setPassword("root");  
  51.             jrs.setCommand("select * from t_student");  
  52.             jrs.execute();  
  53.             System.out.println("id\t姓名\t 性别");  
  54.             while(jrs.next())  
  55.             {  
  56.                 System.out.println(jrs.getString(1)+"\t"+jrs.getString(2)+"\t"+jrs.getString(3));  
  57.             }  
  58.         }  
  59.         System.out.println("=======================");  
  60.         //是不是更简单了呢?我认为还是极好的~ 至少我只知道JdbcRowSet就可以进行数据库操作了,不像原来要创建各种对象  
  61.         //如果RowSet没有提供一个con的话,那么他将使用RowSetReader来完成execute方法  
  62.           
  63.         //下面 我们来看一个离线版的RowSet,关闭数据库连接后仍然能使用的RowSet  
  64.         try  
  65.         (  
  66.                 //由于JdbcRowSet是非离线的 所以 这里我们更换成一个离线的RowSet:CachedRowSet  
  67.                 Connection con=DriverManager.getConnection("jdbc:mysql://localhost/dbtest""root""root");  
  68.                 PreparedStatement pstmt=con.prepareStatement("select * from t_student",   
  69.                                                              ResultSet.TYPE_SCROLL_SENSITIVE,  
  70.                                                              ResultSet.CONCUR_UPDATABLE);  
  71.                 ResultSet rs=pstmt.executeQuery();  
  72.                 CachedRowSet crs=rsf.createCachedRowSet();  
  73.         )  
  74.         {  
  75.             crs.populate(rs); //封装rs成CachedRowSet  
  76.             con.close();  //好了 我们将con这个关闭  
  77.             try  
  78.             {  
  79.                 while(rs.next())  
  80.                 {  
  81.                     System.out.println(rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));  
  82.                 }  
  83.             }catch(Exception e)  
  84.             {  
  85.                 System.out.println("由于con已经关闭,rs不能再被访问");  
  86.             }  
  87.             System.out.println("但是离线的crs仍可访问");  
  88.             System.out.println("id\t姓名\t 性别");  
  89.             while(crs.next())  
  90.             {  
  91.                 System.out.println(crs.getString(1)+"\t"+crs.getString(2)+"\t"+crs.getString(3));  
  92.             }  
  93.         }  
  94.         System.out.println("=======================");  
  95.           
  96.         //演示如果操作数据(这里演示的是如何插入数据)  
  97.         CachedRowSet crs1=rsf.createCachedRowSet();  
  98.         crs1.setUrl("jdbc:mysql://localhost/dbtest");  
  99.         crs1.setUsername("root");  
  100.         crs1.setPassword("root");  
  101.         crs1.setCommand("select * from t_student");  
  102.         crs1.execute();  
  103.           
  104.         //这样的操作只能改变离线的RowSet  
  105.         crs1.moveToInsertRow();  //将指针移动到插入行,当前的位置将会被记住  
  106.         crs1.updateString(1, UUID.randomUUID().toString().replace("-"""));  
  107.         crs1.updateString(2"克隆人"+System.currentTimeMillis());  
  108.         crs1.updateString(3"女");  
  109.         crs1.insertRow(); //必须和moveToInsertRow联合使用  
  110.         crs1.moveToCurrentRow(); //做完插入操作后,将指针指回到插入状态前的行  
  111.         crs1.beforeFirst();  
  112.         while(crs1.next())  
  113.         {  
  114.             System.out.println(crs1.getString(1)+","+crs1.getString(2)+","+crs1.getString(3));  
  115.         }  
  116.           
  117.         //如果想同步数据库那么就需要重新连接数据库,然后把数据提交上去  
  118.         try  
  119.         (  
  120.                 Connection con=DriverManager.getConnection("jdbc:mysql://localhost/dbtest""root""root");  
  121.         )  
  122.         {  
  123.             con.setAutoCommit(false);  //这句必须要否则会造成下面那句的异常  
  124.             crs1.acceptChanges(con);  //同步数据到数据库  
  125.         }  
  126.         System.out.println("=======================");  
  127.           
  128.         //最后我们来看看分页  
  129.         /* 第一种方式 有ResultSet的 
  130.          * crs.setPageSize(pageSize); //设置每页的大小 
  131.          * crs.populate(rs, (page-1)*pageSize+1); //封装rs从第几行(根据页和每页大小算出)开始 
  132.          * 个人觉得这种方式不好,因为 这个实际上还是先查出了所有结果rs,然后再同java的方式截取出咱们想要的那页数据 
  133.          * */  
  134.         crs1.setPageSize(3); //每页显示几条  
  135.         crs1.execute();  
  136.         System.out.println(crs1.isBeforeFirst());  
  137.         int i=1;  
  138.         System.out.println("第"+i+"页:");  
  139.         while(crs1.next())  
  140.         {  
  141.             System.out.println(crs1.getString(1)+","+crs1.getString(2)+","+crs1.getString(3));  
  142.         }  
  143.         i++;  
  144.         while(crs1.nextPage())  
  145.         {  
  146.             System.out.println("第"+i+"页:");  
  147.             while(crs1.next())  
  148.             {  
  149.                 System.out.println(crs1.getString(1)+","+crs1.getString(2)+","+crs1.getString(3));  
  150.             }  
  151.             i++;  
  152.         }  
  153.     }  
  154.   
  155. }  

 

转载请加本站连接: www.cxyapi.com

扩展阅读:

  • 1.RowSet 5个常用子接口介绍

    JdbcRowSet:封装ResultSet,使得它能可以当作JavaBeans使用,但是它必须保持与数据库的连接(非离线)。
    CachedRowSet:拥有JdbcRowSet所有功能,同时还能断开数据库连接进行离线操作。
    WebRowSet:拥有所有的CachedRowSet功能,同时还能通过xml来描述自己(把自己写成xml,通过xml来配置自己)。
    JoinRowSet:拥有所有WebRowSet的功能,同时它能在断开数据源的情况下做一个sql join(感觉就是java版的表连接,比如2个结果集 我通过什么字段将其关联成一个表,sql中的join(联表)操作)。
    FilteredRowSet:有所有哦的WebRowSet的功能,如其名,可以做过滤操作(在不使用查询语句和断开数据源的情况下)。
  • 2.RowSet离线接口解决的问题

    过去使用ResultSet的方式:
    方式1:将结果集遍历,封装成List<Map<String,Object>>,然后关闭数据库连接,使用这个封装好的对象(最常用的形式)
    方式2:再遍历使用ResultSet的过程,数据库连接一直处于打开状态,操作完毕后才关闭数据库连接(简单程序和初学者都这么干)
    分析:方式1就是有一次转换的过程,无形中造成了性能的浪费,方式2的数据库连接一直处于打开状态,性能低且不安全。
    RowSet有很多可离线的子接口,解决了上面两种方式的所有问题,想必这是极好的~
  • 3.关于分页的一些说明

    1.crs.previousPage();可以向前翻页。
    2.每次nextPage都会创建一个新的CachedRowSet,每次只有PageSize条数据在内存中(官方解释 )。
  • 4.关于没有con的execute();执行说明

    如果RowSet不是通过Connection一步一步得到的,那么它的执行是通过RowSetReader完成的。
    详解 待续...