- 浏览: 262754 次
- 性别:
- 来自: 福州
文章分类
最新评论
-
sflscar:
太好了,我搞了一下午,批量插入,第一个参数个数没对sql批量导 ...
redis pipe大数据量导入 -
赵青青:
那 entity.hbm.xml 文件中的主健策略怎么配置 ...
Hibernate 和 Access -
GapStar:
换成flash IconCellRenderer.as应该怎么 ...
DataGrid 中加入图标 -
binbinyouli:
不好意思。我把楼主注释掉得部分打开了。但是我看楼主有传递对象的 ...
Flex Flash 和JAVA 在Socket交互 -
binbinyouli:
不知道前两位评论人时怎么做得。我再做这个例子的时候出现了安全沙 ...
Flex Flash 和JAVA 在Socket交互
分页
由于 CachedRowSet 是将数据临时存储在内存中,因此对于许多 SQL 查询,会返回大量的数据。如果将整个结果集全部存储在内存中会占用大量的内存,有时甚至是不可行的。对此 CachedRowSet 提供了分批从 ResultSet 中获取数据的方式,这就是分页。应用程序可以简单的通过 setPageSize 设置一页中数据的最大行数。也就是说,如果页大小设置为 5,一次只会从数据源获取 5 条数据。下面的代码示范了如何进行简单分页操作。(分页部分代码默认 ORDERS 表中有 10 条数据)
清单 11. 分页代码一
ResultSet rs = stmt.executeQuery(DBCreator.SQL_SELECT_ORDERS); CachedRowSet cachedRS = new CachedRowSetImpl(); // 设置页大小 cachedRS.setPageSize(4); cachedRS.populate(rs, 1); while (cachedRS.nextPage()) { printRowSet(cachedRS); } while (cachedRS.previousPage()) { printRowSet(cachedRS); }
可以看到只需要在 populate 之前使用 setPageSize 设置页的大小,就可以轻松实现分页了。每次调用 nextPage 或 previousPage 进行翻页后,行游标都会被自动移动到当前页第一行的前面,并且只能在当前页内移动。这样我们对每一页都可以像新的数据集一样进行遍历,非常方便。这里需要注意的是:
用来填充 CachedRowSet 的 ResultSet 必须是可滚动的(Scrollable)。
populate 必须使用有两个参数的版本,否则无法进行分页。读者可以将 cachedRS.populate(rs, 1); 换成 cachedRS.populate(rs); 看看会有怎样的情况发生。
ResultSet rs 必须在遍历完毕后才能关闭,否则翻页遍历时会抛 SQLException。
我们注意到在使用分页遍历数据集时,nextPage() 是最先被调用的,也就是说页与行相似,最开始的页游标是指向第 0 页的,通过 nextPage() 方法移到第一页,这样就可以用非常简洁的代码遍历数据集。那么如果在第 0 页时(第一次调用 nextPage)之前使用 next 遍历当前页会是怎样的结果呢?
清单 12. 分页代码二
ResultSet rs = stmt.executeQuery(DBCreator.SQL_SELECT_ORDERS); CachedRowSet cachedRS = new CachedRowSetImpl(); // 设置页大小 cachedRS.setPageSize(4); cachedRS.populate(rs, 1); printRowSet(cachedRS); while (cachedRS.nextPage()) { printRowSet(cachedRS); }
我们看到第一页被输出了两次。也就是说使用 next 始终是可以遍历第一页的,而每次 nextPage 后,行游标都会被重置到当前页的第一行数据之前。对于使用 execute 填充数据的方式,通过 setPageSize 同样可以实现分页。
setMaxRows 可以设置 CachedRowSet 可遍历的最大行数。下面是 setMaxRows 和 setPageSize 同时使用的例子。
清单 13. 分页代码三
ResultSet rs = stmt.executeQuery(DBCreator.SQL_SELECT_ORDERS); CachedRowSet cachedRS = new CachedRowSetImpl(); cachedRS.setPageSize(4); cachedRS.setMaxRows(7); cachedRS.populate(rs, 1); while (cachedRS.nextPage()) { printRowSet(cachedRS); } rs.close();
上面的例子中,分别将页大小设置为 4,最大行数设置为 7(设置页大小时,如果最大行数不等于 0,就必须小于等于最大行数),然后遍历打印所有行,输出如下。
清单 14. 清单 13 中的代码执行结果 The data in RowSet: 1 1 Book 2 1 Compute 3 2 Phone 4 2 Java The data in RowSet: 5 2 Test 6 1 C++ 7 2 Perl
我们注意到,虽然满足 Select 条件的数据有 10 条,但由于我们使用 setMaxRows 设置了允许的最大行数,所以最终我们只得到了 7 条数据。另外 setPageSize 只会改变下一次填充页时的大小,无法影响当前页的大小。我们可以在数据填充完毕后再改变页的大小。
清单 15. 分页代码四
ResultSet rs = stmt.executeQuery(DBCreator.SQL_SELECT_ORDERS); CachedRowSet cachedRS = new CachedRowSetImpl(); cachedRS.setPageSize(4); cachedRS.populate(rs, 1); cachedRS.setPageSize(3); while (cachedRS.nextPage()) { printRowSet(cachedRS); } rs.close();
我们在 populate 数据之前设置的页大小是 4,在 populate 数据之后又将页大小设置为 3,然后遍历输出结果。
清单 16. 清单 15 中的代码执行结果
The data in RowSet: 1 1 Book 2 1 Compute 3 2 Phone 4 2 Java The data in RowSet: 5 2 Test 6 1 C++ 7 2 Perl The data in RowSet: 8 1 Ruby 9 1 Erlang 10 2 Python
我们发现除了第一页有 4 条数据外,其余页都只有 3 条数据。实际上 populate 中就已经对第一页数据进行了填充,并且使用之前设置的 4 作为页大小。所以 populate 之后设置的页大小就只能从第二页开始起作用了。setMaxSize 与此相似,也是在每次填充页时计算。
应注意的问题
在 JDK 5.0 中,当删除一行中某列值为 null 时,会抛出 NullPointerException。例如,表 CUSTOMERS 中第二行第三列的值为 null。假设 cachedRS 里面填充着表 CUSTOMERS 的数据,那么下段代码在 JDK 5.0 下运行时会抛出 NullPointerException。在 JDK 6.0 中,此问题已得到修正。
清单 17.
cachedRS.absolute(2); cachedRS.deleteRow(); cachedRS.acceptChanges();
使用 WebRowSet
WebRowSet 继承于 CachedRowSet,因此用来填充 CachedRowSet 的方式同样适用于 WebRowSet。WebRowSet 也可以读取一个符合规范的 XML 文件,填充自己。假定 CUSTOMERS.xml 是一个符合规范的 XML 文件,里面存放的是表 CUSTOMERS 的数据。
清单 18. 读取 XML 文件
WebRowSet newWebRS = new WebRowSetImpl(); newWebRS.readXml(new FileReader("CUSTOMERS.xml"));
相比于 CachedRowSet,WebRowSet 就是添加了对 XML 文件读写的支持。它可以将自身数据输出到 XML 文件,也可以读取符合规范的 XML 文件,来填充自己。上段示例代码中已经演示了如何读取 XML 文件。如下示例代码则是生成一个 XML 文件。
清单 19. 生成 XML 文件
WebRowSet webRS = new WebRowSetImpl(); CachedRowSetDemo.fillRowSetWithExecute(webRS); // 输出到XML文件 FileWriter fileWriter = new FileWriter("CUSTOMERS.xml"); webRS.writeXml(fileWriter);
fillRowSetWithExecute(CachedRowSet) 是一个静态方法,它的功能是用表 CUSTOMERS 来填充传入的 CachedRowSet。
应注意的问题
按照规范,当一行被标记为更新时,在输出到 XML 文件时,应使用标签 <modifyRow>,但实际输出为 <currentRow>。
按照规范,当一行中某列被更新时,在输出到 XML 文件时,应使用标签 <updateValue>,但实际输出为 <updateRow>。
按照规范,读取 XML 文件时,如果某行标签为 <deleteRow>,在读到 WebRowSet 中时,该行应被标记为删除,实际读取后,状态丢失。
使用 FilteredRowSet
FilteredRowSet 继承自 WebRowSet。正如它的名字所示,FilteredRowSet 是一个带过滤功能的 RowSet。它的过滤规则在 Predicate 中定义。Predicate 也是 javax.sql.rowset 包下的接口,它定义了三个方法:boolean evaluate(Object value, int column),boolean evaluate(Object value, String columnName),boolean evaluate(RowSet rs)。 前两个方法主要是用来检查新插入行的值是否符合过滤规则,符合,返回 true;否则,返回 false。FilteredRowSet 在新插入行时,会用这个方法来检测。如果不符合,会抛出 SQLException。boolean evaluate(RowSet rs) 这个方法则是用来判断当前 RowSet 里面的所有数据,是否符合过滤规则。FilteredRowSet 在调用有关移动游标的方法时,会使用这个方法进行检测。只要符合过滤规则的数据才会显示出来。下面我们给出了一个非常简单的 Predicate 实现,它的过滤规则是每行第一列的值只有大于 1 的才是有效行。
清单 20. Rang.java
class Range implements Predicate { @Override public boolean evaluate(RowSet rs) { try { if (rs.getInt(1) > 1) { return true; } } catch (SQLException e) { // do nothing } return false; } @Override public boolean evaluate(Object value, int column) throws SQLException { return false; } @Override public boolean evaluate(Object value, String columnName) throws SQLException { return false; } }
下面这段代码演示了使用上面定义的 class Range 前后的数据变化。
清单 21.
FilteredRowSet filterRS = new FilteredRowSetImpl(); CachedRowSetDemo.fillRowSetWithExecute(filterRS); System.out.println("/*******Before set filter***********/"); CachedRowSetDemo.printRowSet(filterRS); System.out.println("\n/*******After set filter***********/"); Range range = new Range(); filterRS.setFilter(range); CachedRowSetDemo.printRowSet(filterRS);
清单 22. 清单 21 中的代码执行结果
/*******Before set filter***********/
The data in RowSet: 1 Tom Tom is VIP. 2 Jim null
/*******After set filter***********/
The data in RowSet: 2 Jim null
可以看出,在设置了过滤器后,再次打印 FilteredRowSet 中的数据时,由于第一行第一列的值为 1,不符合过滤规则,因此,没有打印出来。上面实现的这个 Predicate 中,用来检测新插入行是否符合过滤规则的方法直接返回 false。这样,在新插入行时,无论插入什么值时,都将抛出 SQLException。
应注意的问题
当设置了过滤器后,FilteredRowSet.absolute(1) 无论何时都返回 false。按照规范,如果第一行值不符合过滤规则,则移到第二行,依次类推,直到找到第一条符合过滤规则的结果行并返回 true,否则,返回 false。
在 JDK 5.0 下,如果 FilteredRowSet 没有设置过滤器,那么在新插入一行时会抛出 NullPointerException。在 JDK 6.0 中,已解决该问题。
使用 JdbcRowSet
JdbcRowSet 是对 ResultSet 的一个简单的封装,让它可以作为一个 JavaBeans 组件来使用。填充 JdbcRowSet 只能通过一种方式,即 execute() 方法。之后可以通过类似于操作 ResultSet 的方法来操作 JdbcRowSet。
清单 23.
JdbcRowSet JdbcRowSet jrs = new JdbcRowSetImpl(); jrs.setCommand(DBCreator.SQL_SELECT_CUSTOMERS); jrs.setUrl(DBCreator.DERBY_URL); jrs.execute(); while (jrs.next()) { for(int i = 1; i <= jrs.getMetaData().getColumnCount(); i++) { System.out.print(jrs.getObject(i) + " "); } System.out.println(); }
评论
我就用的jdk1.6 我怎么没发现修正了啊
发表评论
-
redis pipe大数据量导入
2015-07-06 18:48 14215由于做性能测试,需要往redis中导出千万 ... -
Tongweb、Tomcat远程调试
2014-04-15 21:01 3689在开发过程中经常需要对布署在远程的程序进行跟踪测 ... -
JAVA中Integer 和 int 的比较
2012-06-17 15:04 838http://topic.csdn.net/u/2012060 ... -
java给图片加水印,文字水印
2010-10-09 10:03 1163package com.newland.bi.tt; i ... -
Struts+jsonplugin
2010-04-19 20:42 1094JSON官方文档 http://www.json.org/j ... -
jsp session 丢失
2010-04-19 20:37 23621.先访问a站点:http://192.168.18.2/te ... -
读取Properties的N种方法
2009-12-14 10:55 937如何读取资源文件:( ... -
Java正则表达式详解(上)
2009-03-28 10:24 958如果你曾经用过Perl或任 ... -
JAVA数据库基本操作指南
2009-03-28 10:04 965转自:http://www.qqread.com/java/2 ... -
不同Web主机上的Servlet之间数据对象的相互传输
2009-03-03 10:48 1282由于数据库服务器A和服务库服务器B之间存在着数据的交换,而WE ... -
与常用支付平台接口
2009-03-03 10:10 1370step-by-step集成阿里巴巴支付宝接口 http:// ... -
Java 6 RowSet 使用完全剖析(3)
2009-03-02 19:31 1196清单 24. 清单 23 中的代码执行结果 1 Tom Tom ... -
Java 6 RowSet 使用完全剖析(1)
2009-03-02 18:52 1893javax.sql.rowset 自 JDK 1.4 引入,从 ... -
关于log4j配置文档详解
2009-02-25 14:39 793一.参数意义说明输出级别的种类ERROR、WARN、INFO、 ... -
Log4j最简入门(很不错的Log4j入门)
2009-02-25 14:34 833<!--[if !supportLists]--> ... -
Java对象的序列化和反序列化实践
2008-12-29 14:38 920引:当两个进程在进行远 ... -
Java语言中的参数传递详解
2008-12-24 08:41 837和其它程序设计语言类 ... -
set map table list总结
2008-10-13 11:39 1418<转自>http://bluefishyong. ... -
多态的运用 实现java 数据类型判断
2008-09-03 12:54 2420package javaBasic;/** *//** * 用 ... -
java关于23种java关于23种设计模式的有趣见解 设计模式的有趣见解
2008-09-03 12:48 1360创建型模式 1、FACTORY— ...
相关推荐
Java 6 RowSet 使用完全剖析
Java 6 RowSet 使用完全剖析 结合Spring2.0和ActiveMQ进行异步消息调用 struts+hibernate增删改查(一) AXIS 布署问题 struts+hibernate增删改查(二) MySQL中如何实现Top N及M至N段的记录查询?...
必须要时从Java SE API的源代码分析,了解各种语法在Java SE API中如何应用。 《Java JDK 7学习笔记》将IDE操作纳为教学内容之一,使读者能与实践结合,提供的视频教学能更清楚地帮助读者掌握操作步骤。 内容简介 ...
Java历史 2 Java技术概述 3 Java技术的优点 3 Java虚拟机 4 类加载器 6 Windows环境变量 8 内容总结 13 独立实践 14 第二章: 面向对象概述 15 学习目标 15 面向对象(Object Oriented) 16 面向对象的主要特性 18 ...
使用JSP进行数据访问 访问数据 范例应用程序 深入性主题 小结 第17章 分析和生成XML 文档和数据 XML概述 Java XML技术 生成XML 读取XML 小结 第18章 WAP客户机 WAP概览 ...
12. **接口与实现**:如RowSet接口,它的实现类如Java POI的 JRSSerializableRowSet 和 JdbcRowSetImpl,可将Excel数据作为JDBC结果集处理。 使用Apache POI时,开发人员需要了解这些基本概念,并根据实际需求选择...
- **内存分析**:学习Java内存模型,理解栈、堆以及垃圾回收机制。 - **递归**:学习如何编写和理解递归函数。 - **集合类**:熟悉ArrayList、LinkedList、HashSet、HashMap等数据结构的使用。 - **泛型**:学习...
深入理解内存分析、递归以及集合类(如ArrayList、LinkedList和HashMap)的使用。泛型提供类型安全,自动打包与解包简化了数据类型的转换。Annotation用于元数据,IO流处理文件操作,多线程和线程同步(如...
2. **使用JDBC**: 使用JDBC通常包括以下几个步骤: - **注册驱动**:通过`Class.forName()`方法加载特定数据库的JDBC驱动。 - **建立连接**:使用`DriverManager.getConnection()`方法连接到数据库,需提供URL、...
- **PoC示例**:通过构造特定的JSON数据格式(如使用`com.sun.rowset.JdbcRowSetImpl`类)可以触发远程代码执行漏洞。 - **修复措施**:添加黑名单机制,禁止加载敏感类。 - **Weblogic安全漏洞**: - **CVE-...
深入理解内存分析,了解递归操作,掌握集合类(如ArrayList、LinkedList、HashMap等),泛型的使用,自动装箱拆箱原理,以及Annotation(注解)的使用。此外,还需要学习多线程编程,包括线程的创建、同步...
在Java中,通过`java.util.regex`包来实现正则表达式的使用。 - 常见的正则表达式操作包括`Pattern`和`Matcher`类,用于编译和匹配正则表达式。 #### 反射机制 - Java的反射机制允许运行时获取类的信息并创建对象。...
本文将深入探讨JDK 1.4、JDK 1.5(也称为Java 5)和JDK 6这三个重要版本的关键特性。 **JDK 1.4** JDK 1.4是Java发展历程中的一个里程碑,发布于2002年。这个版本引入了许多关键的新特性,包括: 1. **异常链**:...
- 在可能的情况下,限制或完全避免使用反序列化功能,特别是对于不受信任的数据。 - 使用更安全的数据交换格式替代Java对象序列化。 - 采用自动化工具和库来帮助识别和修复潜在的安全漏洞。 整体而言,本文档深入...
RowSet.java、RowSetMetaData.java、PooledConnection.java、RowSetInternal.java、StatementEventListener.java、StatementEvent.java、2mConnectionEvent.java、RowSetReader.java:这些文件名暗示了程序可能使用...
- ojdbc是Oracle提供的JDBC驱动,例如ojdbc8.jar,它是Type 4驱动,完全用Java编写,无需安装Oracle客户端。 - 配置数据源:在Java应用中,可以配置DataSource对象,提供更高级的连接池管理,提高性能和资源利用率...