`
hulunberbus
  • 浏览: 858319 次
文章分类
社区版块
存档分类
最新评论

JDK 1.5学习之RowSet

 
阅读更多
在jdk1.4的javax.sql包中有一个RowSet接口,但是没有具体实现的类。"Tiger"诞生之后,引入了 javax.sql.rowset包中的五个子接口和com.sun.rowset包里面的对应的五个实现类,这样我们就可是使用功能强大的 RowSet了。jdk1.5中RowSet的五个子接口分别是JdbcRowSet,CachedRowSet,WebRowSet, JoinRowSet和FilteredRowSet,他们为我们的数据库开发带来了强大的功能和方便的操作。
我的java环境是:RedHat9
Jdk1.5.1_01
Eclipse3.1m4
MySql4.1.10(JDBCDriver:org.gjt.mm.mysql.Driver)
我首先在test数据库里面创建了两个表用于这次的学习,下面是脚本:
createtabletable1(idintnotnull,namevarchar(20)notnull);
createtabletable2(idintnotnull,infovarchar(20)notnull);
然后我就插入了一些数据用于测试。以下内容以我的环境示意,大家只要修改相应地方就可用于自己的测试。
RowSet 对象可分为两类:有连接的和无连接的。JdbcRowSet是唯一一个有连接的实现,和传统的ResultSet一个样,有连接的实现是基于Jdbc驱动 的连接,数据库的连接是贯穿整个对数据库的操作。而无连接的实现是基于Reader和Writer流的连接,在需要读取数据和写入数据的时候才建立连接, 在整个操作过程中都是断开连接的,后面四个接口对象都是无连接的实现。下面我就针对每一个接口来介绍一下它们各自的功能。
JdbcRowSet接口:
我的理解是这个接口基本上和ResultSet有类似的功能,只不过它的结果集默认是ResultSet.TYPE_SCROLL_INSENSITIVE和ResultSet.CONCUR_UPDATABLE的,也就是说默认的结果集就是可以上下滚动和可更新的。
因 为本身RowSet接口就是ResultSet的子接口,所以1.5里面的所有RowSet都有ResultSet的方法,而JdbcRowSet又只是 在默认的属性和ResultSet有区别,所以它对结果集的操作方法和ResultSet都是一样的,我就不具体介绍了,大家可以参考API。
下面我介绍一下JdbcRowSet的创建方法,这有两种方法,一种是基于传统的JDBC连接数据库的方法:
Class.forName("org.gjt.mm.mysql.Driver");
Connectionconn=DriverManager.getConnection("jdbc:mydql://localhost:3306/test ","root',"");
Statementstmt=conn.createStatement();
ResultSetrs=stamt.executeQuery("select*fromtable1");
JdbcRowSetjrs=newJdbcRowSetImpl(rs);
这 样就创建了一个对象(JdbcRowSetImpl是com.sun.rowset包里面的实现类,文中的五个接口在包中都对应有一个实现类),这个对象 里面的数据就是和rs里面的数据是一样的。还有一种创建的方法是使用默认的构造方法,然后set属性得到数据,个人推荐使用第二种方法:
JdbcRowSetjrs=newJdbcRowSetImpl();
jrs.setUrl("jdbc:mydql://localhost:3306/test");
jrs.setUsername("root");
jrs.setPassword("");
jrs.setCommand("select*fromtable1");
jrs.execute();
这样创建的对象是和第一种方法是一样的结果。当然这种方法可以连接一个数据源,如果我们在上下文环境种绑定了一个数据源,JNDI名字是dataSource1,那么下面的代码就可以获得对象:
JdbcRowSetjrs=newJdbcRowSetImpl();
jrs.setDataSourceName("dataSource1")
jrs.execute();
得到对象之后我们就可以使用相应的方法来对数据进行遍历,更新,插入或者删除。
我 有2点要说明:第一,其它四个接口的对象中除了JoinRowSet创建方式基本都是一样的,只是接口名字和接口实现类的名字不同而已,后面我就不再说明 创建对象的方法了。第二,虽然JdbcRowSet默认是可滚动和可更新的,但是这也是需要数据库驱动支持的,我使用的MySql驱动就不支持更新结果 集,所以大家使用之前需要阅读驱动的说明文档。
CachedRowSet接口:
它继承于RowSet接口,而且他是无连接的RowSet的其他3个实现的父接口,也就是说其他3个接口都直接或者间接继承了它。从名字我们可以知道,它的原理就是读入数据保存在缓存进行相应的操作。
创 建接口对象除了上面的两种创建方式,还有一个方法,就是在构造方法里面传递一个SyncProvider。之前我说过无连接的RowSet都是基于流读写 的,那么这里所说的SyncProvider就是提供了特定的Reader和Writer。jdk1.5文档的Sample Coder有这样的实现:
Stringprovider="com.fred.providers.HighAvailabilityProvider"
CachedRowSetcrs=newCachedRowSetImpl(provider);
这 样我们就为RowSet设置了特定的Reader和Writer,但是这是需要第三方的包支持的。而我们使用无参的构造方法创建的对象是使用了默认的 SyncProvider,当然一般来说这对于我们就已经足够了。创建了对象之后就可以使用和JdbcRowSet一样的方法来进行就结果集 的增删改操作了,但是唯一不同的就是在更新了结果集之后必须调用Writer将缓存中的数据写入数据库,而其方法就是crs.acceptChages ();
CachedRowSet提供的最令人兴奋的功能就是分页功能。以前程序员很头疼的问题就是怎么处理数据分页而不影响性能,现在有了CachedRowSet一切都变得那么简单,请看下面的代码:
CachedRowSetcrs=newCaehedRowSetImpl();
crs.setUrl("jdbc:mydql://localhost:3306/test");
crs.setUsername ("root");
crs.setPassword("");
crs.setCommand("select*fromtable1");
crs.setPageSize(5);
crs.execute();
while(crs.nextPage())
while(crs.next())
System.out.println(crs.getInt ("id"+"/t/t"+crs.getString("name"));
我们在crs.execute()之前设置每页的数据行数,那么Reader读取数据的时候就只读指定的行数的数据,这样我们就避免了一次读取所有数据再进行分页操作。是不是很简单呢?

JoinRowSet接口:
这个接口可以提供我们在无连接的状态下直接对结果集进行Join。下面的代码提供了JoinRowSet的实现:
CachedRowSetcrs1=newCaehedRowSetImpl();
crs1.setUrl("jdbc:mydql://localhost:3306/test");
crs1.setUsername("root");
crs1.setPassword("");
crs1.setCommand("select*fromtable1");
crs1.execute();
CachedRowSetcrs2=newCaehedRowSetImpl();
crs2.setUrl("jdbc:mydql://localhost:3306/test ");
crs2.setUsername("root");
crs2.setPassword("");
crs2.setCommand ("select*fromtable2");
crs2.execute();
JoinRowSetjrs=newJoinRowSetImpl();
jrs.addRowSet(crs1,"id");
jrs.addRowSet(crs2,"id");
while(jrs.next())
System.out.println(jrs.getInt ("id")+"/t/t"+jrs.getString("name")+"/t/t"+jrs.getString("info");
这 段代码的作用和执行select*fromtable1innerjoin table2ontable1.id=table2.id语句得到的结果集是一样的。但是我个人认为与其这样复杂地使用 JoinRowSet,不如直接使用这条Join语句来得到CachedRowSet。
默认的Join是innerjoin的, 接口还支持crossjoin,fulljoin,leftouterjoin和 rightouterjoin,我们通过setJoinType()方法来修改连接类型,当然这还是需要数据库的支持。还有一个 值得注意的地方就是,在这个例子里我连接的列在两个表里面都叫id,那么我们取数据的时候就使用id这个名字,那如果两列的名字不一样呢?系统就会为这个 连接列取一个默认的名字叫做"MergedCol"。
FilteredRowSet接口:
.NET的ADO.NET支持 获取结果集使用一定的条件过滤从而得到不同的结果,那现在jdk1.5也能做到了,FilterRowSet接口让我们可以灵活地定义过滤条件达到不同的 效果。Javax.sql.rowset包里面的Predicate接口就是这个过滤器,我们通过实现这个接口定义过滤条件,下面是示意代码:
publicclassFilterimplementsPredicate{
privateintmin;
privateintmax;
privateStringcolName;
publicFilter(intmin,intmax,StringcolName){
this.min=min;this.max=max;this.colName=colName;
}
publicbooleanevaluate(RowSetrs){
CachedRowSetcrs=(CachedRowSet)rs;
if((crs.getInt(colName)>min)&&(crs.getInt(colName)<max))
returntrue;
elsereturnfalse;
}
}
下面我们就使用这个过滤器来过滤掉id不在min和max之间的数据:
FilteredRowSetfrs=newFilteredRowSet();
……
frs.setCommand("select*fromtable1");
frs.execute();//先获取所有数据;
frs.setFilter(newFilter(1,20,"id");//过滤掉id值不在1和20之间的数据;
因为实现Prdicate接口里面的方法很灵活,所以我们就能很灵活地设置过滤条件,我们就可以只通过一条语句得到不同的结果。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics