Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1503981
  • 博文数量: 3500
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 43870
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-03 20:31
文章分类

全部博文(3500)

文章存档

2008年(3500)

我的朋友

分类:

2008-05-04 20:55:58

一起学习
在阅读本文之前,你需要了解Pet Store的J2EE模式 () 在Pet Store中的CatalogDao使用了DAO模式,从而完成Fast-Lane Reader模式,以便能快速的输出数据库元素 列表,同时使用for page-by-page iteration完成每页的输出显示。 在CatalogDAOImpl 中基本返回的是Page,也就是说,在CatalogDAOImpl的具体JDBC数据库查询时,就将Page功 能融入其中,从而一步到位的完成输出显示。 但在实际系统应用中,我们都有用户权限约束,也就是说,并不是每条数据库记录都能被显示输出,有些用户 就只能看到他被授权看到的的记录。 Jive中的Iterator模式就很好的解决了这个问题,Jive中使用Proxy模式完成用户权限级别的验证,同时为了更 快的获得数据库记录和节约内存,Jive专门建立了自己的Iterator模式,这些一开始让人疑惑,直接使用 Collection的Iterator不是更好,虽然简单方便了,但是前提是在内存中要先开辟一块Collection内存,如果 数据库记录很大,将耗费很多内存,致使系统瘫痪(细节讨论见 ) Jive的Iterator不只是传递了数据库指针,而且加载了权限验证功能,因此,这一模式是实用可行的,那么在 我们自己的EJB应用中如何综合这两个系统的模式优点? 这其中应该有很多中间方案可行,如果你有兴趣可以贴出你的想法,我目前采取的是DAO模式和Jive的Iterator 模式集合,也就是说,在自己的EJB中不直接返回Page 而是返回Iterator,这个Iterator是类似Jive中的 DatabaseObjectIterator。 简单的说,由于Jive不是EJB架构,所以,将Jive中的访问数据库段用DAO模式替代,其他都可以照搬Jive的 Iterator模式,关于前端JSP页面的分页输出,这时可以参考Pet Store的page-by-page iteration模式,也就 是说,根据Iterator模式再拓展写Page,结构和功能类似Pet store的Page. 这里只提供一个大体思路,如果要写透彻真是很长,看看平常我们以前用ASP PHP做的数据库查询分页的简单功 能蕴含这么多新的思想,其实这些思想也是在ASP PHP应付大数据库量失败的总结,所以软件质量控制是显得多 么重要。 我用Iterator的程序代码: public interface DataListIterator { /** * 功能类似于java.util.Iterator.hasNext() * * @return 如果有下一个元素,返回true * @throws Exception */ public boolean hasNext() throws Exception; /** * 功能类似于java.util.Iterator.next(),但是返回的是数据库查询的结果 * 的字段值字符串数组。 * * @return String[] 字段值字符串数组 * @throws Exception */ public String[] next() throws Exception; } public interface DataList{ /** * 取出指定位置查询结果中的字段值,放到一个字符串数组中并返回。 * 功能类似于java.util.List.get(int) * * @param index 查询结果的索引 * @return String[] 结果中的字段值数组 * * @throws Exception */ public String[] get(int index) throws Exception; /** * 检查查询结果的集和是否为空集合 * * @return boolean true表示空集合 * @throws Exception */ public boolean isEmpty() throws Exception; /** * 检查是否还有下一个查询结果 * * @return boolean true表示有下一个 * @throws Exception */ public boolean hasNext() throws Exception; /** * 检查在指定位置上是否有查询结果 * * @param index 查询结果的索引 * @return boolean true表示有查询结果 * @throws Exception */ public boolean isElementExist(int index) throws Exception; /** * 把游标放到指定的位置上,功能类似于java.sql.ResultSet.absolute(int) * * @param index 指定的位置,从0开始 * @return boolean true表示操作成功 * @throws Exception */ public boolean absolute(int index) throws Exception; /** * 把游标放到查询结果的最前面,功能类似于java.sql.ResultSet.beforeFirst() * * @throws Exception */ public void beforeFirst() throws Exception; /** * 把游标放到查询结果的第一个,功能类似于java.sql.ResultSet.first() * * @return boolean true表示移动成功 * @throws Exception */ public boolean first() throws Exception; /** * 把游标放到查询结果的最后一个,功能类似于java.sql.ResultSet.last() * * @return boolean true表示移动成功 * @throws Exception */ public boolean last() throws Exception; /** * 取得整个查询结果的大小,功能类似于java.util.List.size() * * @return size 查询结果的大小 * @throws Exception */ public int size() throws Exception; /** * 提供一个可以遍历查询结果的对象,功能类似于java.util.List.iterator() * * @return DataListIterator 可以遍历查询结果的对象 * @throws Exception */ public DataListIterator iterator() throws Exception; } public interface DataListHandler{ /** * 得到查询结果的一个子集 * * @param startIndex 子集的起始位置 * @param count 子集的个数 * @return Datalist 返回一个子集 * @throws Exception */ public DataList getListChunk(int startIndex, int count) throws Exception; /** * 取得整个查询结果的大小,功能类似于java.util.List.size() * * @return size 查询结果的大小 * @throws Exception */ public int size() throws Exception; /** * 检查子集的前面是否还有查询结果 * * @return boolean true表示前面还有查询结果 */ public boolean hasPrevious(); /** * 检查子集的后面是否还有查询结果 * * @return boolean true表示后面还有查询结果 * @throws Exception */ public boolean hasNext() throws Exception; /** * 关闭对象 * @throws Exception */ public void close() throws Exception; } * @version 1.0 * * Page实现了DataListHandler。 * * 用于操作ResultSetDataList对象,对查询结果集进行分页显示。在进行显示的期间,必须 * 保持数据库连接Connection和结果集ResultSet没有关闭。 * 基本使用方法举例: *

 *              int index = 4, count = 10;//显示第5到第14条记录

 *              Connection conn = Pool.getConnection();

 *              //(1)使用一个QueryDAO的具体子类来初始化页对象

 *              ResultSetQueryDAO dao = new ResultSetQueryDAO();

 *              ResultSetPage page = new ResultSetPage(conn, dao);

 *

 *              //(2)或者直接使用一个ResultSet对象来初始化页对象

 *              //ResultSet rs = ...;

 *              //ResultSetPage page = new ResultSetPage(conn, rs);

 *

 *              //需要显示的当前页chunk

 *              DataList chunk = page.getListChunk(index, count);

 *              //当前页的前后是否还有记录,用于显示PRVEIOUS和NEXT按钮

 *              boolean hasPrevious = page.hasPrevious();

 *              boolean hasNext = page.hasNext();

 *              //遍历显示当前页的记录

 *              DataListIterator it = chunk.iterator();

 *              while (it.hasNext())

 *              {

 *                  String[] valuesOfRow = it.next();

 *                  for(int i = 0; i < valuesOfRow.length; i  )

 *                      System.out.println(valuesOfRow[i]);

 *              }

 *

 * 
* * @see QueryDAO * @see DataListIterator */ import java.sql.*; public class ResultSetPage implements DataListHandler{ private Connection conn = null; private ResultSet rs = null; private ResultSetDataList dl = null; private RowMapper mapper = null; private QueryDAO dao = null; private int indexOfDataList = 0, countPerPage = 0; /** * 构造函数,提供用于查询的DAO具体对象。 * * @param conn 数据库连接 * @param dao 用于查询的DAO具体对象 * @throws SQLException * */ public ResultSetPage(Connection conn, QueryDAO dao) throws SQLException { this.conn = conn; //使用使用DAO具体对象查询 this.rs = (ResultSet)dao.doQuery(conn); initiateDataList(); } /** * 构造函数,直接提供查询的结果集。 * * @param conn 数据库连接 * @param rs 查询的结果集 * @throws SQLException */ public ResultSetPage(Connection conn, ResultSet rs) throws SQLException { this.conn = conn; this.rs = rs; initiateDataList(); } /** * 得到被查询的字段名称数组 * * @return String[] 字段名称数组 */ public String[] getColumns() { return mapper.getRowColumns(); } /** * 得到查询结果的一个子集 * * @param startIndex 子集的起始位置, 从0开始 * @param count 子集的个数 * @return Datalist 返回一个子集 * @throws Exception */ public DataList getListChunk(int startIndex, int count) throws Exception { if(dl == null) throw new Exception("还没有执行查询或者查询过程出现异常!"); indexOfDataList = Math.abs(startIndex); countPerPage = Math.abs(count); return new ResultSetDataListChunk(dl, indexOfDataList, countPerPage); } /** * 取得整个查询结果的大小,功能类似于java.util.List.size() * * @return size 查询结果的大小 * @throws SQLException */ public int size() throws SQLException { if(dl == null) throw new SQLException("还没有执行查询或者查询过程出现异常!"); return dl.size(); } /** * 检查子集的前面是否还有查询结果 * * @return boolean true表示前面还有查询结果 */ public boolean hasPrevious() { if(indexOfDataList == 0) return false; else return true; } /** * 检查子集的后面是否还有查询结果 * * @return boolean true表示后面还有查询结果 * @throws SQLException */ public boolean hasNext() throws SQLException { if(indexOfDataList countPerPage >= dl.size()) return false; else return true; } /** * 关闭对象 * @throws SQLException */ public void close() throws SQLException { if(rs != null) { rs.close(); rs = null; } if(conn != null) { conn.close(); conn = null; } mapper = null; } /** * helper方法,设置印射,生成包含结果计的ResultSetDataList对象 * * @throws SQLException */ private void initiateDataList() throws SQLException { //设置印射,生成包含结果计的ResultSetDataList对象 mapper = new ResultSetRowMapper(rs); dl = new ResultSetDataList(mapper, conn, rs); } } public interface QueryDAO{ /** * 执行查询操作 * * @param conn 数据库连接 * @return Object 查询结果(ResultSet或者RowSet)。 * @throws SQLException */ public Object doQuery(java.sql.Connection conn) throws java.sql.SQLException; } 在jsp/serlvet中调用: ResultSetPage groupPage = groupManager.groups(); DataList chunk = groupPage.getListChunk(0, 50); //chunk.size() 为结果集大小,可用于分页 DataListIterator it = chunk.iterator(); while (it.hasNext()) { String[] valuesOfRow = it.next(); } 作者简介: 21岁,大学计算机系专业,现正致力于JAVA开发,对JAVA的桌面应用系统开发和WEB相关技术有一定研究,曾开发jant,jzip,小型游戏,JDBC..etc,对J2EE/J2ME充满信心。 你可以通过网站:、 OICQ:29578635,878229,email:kkjvk12@yeah.net和vincent联系。 下载本文示例代码


谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器谈谈设计模式中的Iterator迭代器
阅读(115) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~