2008-05-17

分页方案

改行了,不再做软件开发了,之前工作中做过的一些有价值的东西陆续发布在这,希望对其他人有用。

(这个方案是应用于Swing环境下的。需要调整到Web环境的话,前端控件要重新开发,并且要解决和Web框架的集成,但核心机制是不变的。)
(图片看不到的话,请下载打包了文档和代码的附件^^)
------------------------------------------------------------
分页方案说明

方案简介:
分页方案为客户端开发用户提供这样一套机制:它托管用户的所有待浏览记录或查询记录相关的参数信息,而后根据用户的分页请求提供相应的记录。

实现说明:
一、核心结构
分页方案围绕着由分页控件建立的机制展开,相关的结构如下:

<图片>

分页控件是用于进行翻页的可视化控件,该控件建立了这样一种机制:根据用户的翻页请求,从IPagingWorker中取得相应的记录,并显示到IPagingViewer中。而通过PagingHelper,用户可以简单方便的创建实用的IPagingViewer和IPagingWorker。
典型的使用方式如下:
PagingComponent pagiComp = new PagingComponent();
pagiComp.setPageSize(12);
pagiComp.setPagingViewer(PagingHelper.createPagingViewerFor(mTable));
pagiComp.setPagingWorker(PagingHelper.createPagingWorkerFor(client.query(params))); //(或
pagiComp.setPagingWorker(PagingHelper.createPagingWorkerFor(ModuleIDs.MODULE_PROD, "productService", "queryProductList", new Class[] {Product.class}, new Object[] {paraObj}));
//...

二、助手类
PagingHelper,是为方便分页控件使用的助手类,当前主要用于(根据用户参数信息)创建IPagingViewer和IPagingWorker。默认实现的IPagingViewer,可以自动识别常见的界面控件及其Model,像CExtTable/CExtTableModel、CExtList/ DefaultListModel等,通过调用相应的方法而给其设置新值/记录集。
默认实现了两个IPagingWorker,一个简单的托管用户传入的待浏览记录集;一个托管用户查询记录所需的服务及方法名、参数等信息,通过服务器端的相应支持,可以自主获取所需范围的记录。

三、后台支持
IPagingWorker的第二种默认实现的相关结构如下:

<图片2>

MethodPagingWorkerImpl托管了用户查询记录所需的服务及方法名、参数等信息,使用这些信息,通过PagingService可以获得总记录数等相关信息,通过UserService(用户的服务)可以获得指定范围的记录。
注意,指定范围的记录是通过UserService获得的,而原本的UserService以及相关的UserDAO是不能获取指定范围的记录的。这是怎么回事呢?
分页所需的额外信息是通过用户参数对象携带的(这要求改造用户参数对象,使之能存放除正常用户数据之外的信息;一般可通过DynamicBean及其实现类DynamicBeanImpl来完成),由MethodPagingWorkerImpl在客户端存入,并由UserDAO在服务器端取出并使用。用户可以通过PagingUtils来从用户参数对象中存取这些信息,该类封装了相关的实现细节。相关的示例代码如下:
return getSqlMapClientTemplate().queryForList("T_PRODUCT. selectByProdObj", paraObj, PagingUtils. getSkipResults (paraObj), PagingUtils. getMaxResults(paraObj));

(注:更多的设计及实现细节,请参阅相关的Rose设计及源码。)

使用要点:
在使用分页方案的过程中,用户需要做的工作如下:
1、在UserPanel中,创建PagingComponent,设置每页记录数,并调用PagingHelper的相应方法创建PagingViewer和PagingWorker来配置它;(如果创建的是PagingWorker的MethodPagingWorkerImpl实现,继续)
2、服务器端,在DAO实现中,把原来调用SqlMapClientTemplate的queryForList (statementName, parameterObject)方法的地方,改为调用queryForList (statementName, parameterObject, skipResults, maxResults)方法。而skipResults、maxResults的值,可通过PagingUtils的相应方法获得;(可选)
3、用DynamicBean/DynamicBeanImpl改造相应的参数对象。(可选)

注:a)上述2、3步的任何一步缺失,均不会造成程序运行异常,但会使方案达不到真正的分批获取并缓存记录的效果,而是一次性全部获取并缓存在客户端;
b)另外,即使使用的是PagingWorker的SimplePagingWorkerImpl实现,也可以在所有相关的DAO及参数Model的代码中做上述2、3步的调整,不会造成程序运行异常。
评论
tminglei 2008-05-20
不客气^^
其实方案的精髓,在于想法和思路
蓝色痕迹 2008-05-19
非常感谢,分享万岁.
祝你在新的职业旅途上一帆风顺!
tminglei 2008-05-18
这个方案推出的时候让人拍案叫绝,它的妙处在于:不需要调整现有代码,就可以给很多常用控件(主要是table、list)添加分页的功能。^^
发表评论

您还没有登录,请登录后发表评论

tminglei
搜索本博客
最近加入圈子
最新评论