服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

谈谈设计模式中的iterator迭代器


  在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内存,如果
  
  数据库记录很大,将耗费很多内存,致使系统瘫痪(细节讨论见
  http://www.jdon.com:81/jive/thread.jsp?forum=16&thread=302)
  
  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;

扫描关注微信公众号