首先ecside展现列表、排序、过滤(该三种操作以下简称为 RSF )的实现原理完全和原版EC一样,
如果您对原版EC的retrieveRowsCallback、sortRowsCallback、filterRowsCallback 非常熟悉,那么可以忽略此文.

先来简单介绍一下RSF操作方式.
ecside对数据的展现操作有三种:分页展现,按列排序(目前只支持单列),按列过滤(支持多列联合过滤)
(该三种操作以下简称为 RSF )

ecside提供了两种方式来实现RSF操作 : 基于java collection层 和 基于数据库层,下面先简单介绍一下原理:

=========================================================
一:基于java collection层:
这是ec的默认实现方式, 最简单易用.

您要做的就是将整个列表所要展现的全部数据放入collection 内,并交给EC来处理.
其中RSF操作,全部由EC在内存中完成,由于您已经将全部数据放入了collection中,
所以排序 过滤都是基于全部数据的.

您要在DAO中做的就是一个 查询操作,SQL语句中不需要加入 关于排序 分页 过滤的代码.

这种方式的优点非常明显:实现简单.

缺点同样明显,而且在很大程度上是致命的: 数据量大的时候速度慢,而且很可能outofmemery.

这时候我们就需要第二种方式了:

方式一您所要做的工作:
1 通过DAO,查询出所有的数据,放入collection内
2 将collection传给列表页面

二:基于数据库层:

在这种方式下,EC的角色发生了一点点变化.
此时,EC负责把 collection 里的内容展现出来, 同时会向您提供RSF相关的参数.
而这些参数需要您自己手动取得 并传入到DAO中(当然EC提供了很多方便的方法来帮助您取得这些参数),
具体功能的实现需要您自己在DAO中组织相应的SQL语句.

方式二您所要做的工作:
1 查询出所有的数据的总数
2 取得一个ECSide提供的Limit对象
3 在该对象的帮助下取得RSF操作的相关信息(如 数据的起止行数,排序的列和顺序,过滤的列和内容)
4 将RSF操作的相关信息传入DAO内,来进行SQL语句的拼装(或者其他的操作,如使用ORM工具时)
5 通过DAO,查询出当前页所要显示的数据,放入collection内
6 将collection传给列表页面

这种方式的优缺点正好和方式一相反.

关于两种方式的配置可以看一下 ecside.properties 文件中的下列内容

[code]
table.filterRowsCallback.process=org.extremecomponents.table.callback.ProcessRowsCallback  
table.filterRowsCallback.limit=org.extremecomponents.table.callback.LimitCallback  
 
table.sortRowsCallback.process=org.extremecomponents.table.callback.ProcessRowsCallback  
table.sortRowsCallback.limit=org.extremecomponents.table.callback.LimitCallback  
 
table.retrieveRowsCallback.process=org.extremecomponents.table.callback.ProcessRowsCallback  
table.retrieveRowsCallback.limit=org.extremecomponents.table.callback.LimitCallback  
[/code]

其中 ProcessRowsCallback 采用了方式一 ,LimitCallback采用了方式二
而table.retrieveRowsCallback.default会告诉EC您默认使用的是哪个.
同样您也可以在 ec:table 标签里 指定

[code]
<ec:table filterRowsCallback="process/limit"  sortRowsCallback="process/limit"  retrieveRowsCallback="process/limit" ... >  
[/code]

大家可能还看到了 org.ecside.table.callback.CommonLimitCallback 这个是我自己随意组合出来的一个rowcallback
他在执行分页的时候,使用了方式二,而排序 过滤的时候使用了方式一
所以,大家可能会发现,DEMO中的排序 过滤方法只对当前页有效.
我这么做其实是一种偷懒的方式,但多数情况下,正如网友所说"只排当页数据毫无意义",您们说的没错,的确如此:)

==========================================
下面看一个简单的例子: (以 struts + dao 的方式演示,例子中采用的是ECSide 2.0 RC1版本)

jsp代码
[code]

<ec:table
retrieveRowsCallback="limit"
sortRowsCallback="limit"
filterRowsCallback="limit"
...... >
......
</ec:table>

[/code]

在上面的JSP代码中,指定了所有的RSF操作都使用基于数据库层的.

action的代码
[code]

//默认每页显示的记录条数
 protected static int DEFAULT_PAGE_SIZE = 20;

// 数据库端分页,适合数据量较大的情况
 public ActionForward doQuery(ActionMapping mapping, ActionForm form,
 HttpServletRequest request, HttpServletResponse response)
 throws Exception {
  UserInfoDAO userInfoDAO=(UserInfoDAO)getBean("userInfoDAO");
 
// 当列表的分页 过滤 排序等操作是基于数据库时,必须要用到Limit对象.
// 注意,当页面有多个ec的时候,需要使用带 tableId参数的同名方法.
 //Limit limit=RequestUtils.getLimit(request,"ecGird的Id");
    
  Limit limit=RequestUtils.getLimit(request);
// 基于数据库的排序.
// ECSide会帮助开发人员取得排序的相关信息:当前是按哪个(目前只支持单列排序)column排序的,以及排序的方式desc或asc,
// 这个信息以key-value方式存放在map里.
// 但是至于如果处理这些信息(如组装成sql语句),则是由开发人员自己在DAO里完成的.
  Sort sort=limit.getSort();
  Map sortValueMap = sort.getSortValueMap();
    
// 基于数据库过滤.
// ECSide会帮助开发人员取得过滤的相关信息:当前是对哪些column进行过滤,以及过滤的内容是什么,这个信息以key-value方式存放在map里.
// 但是至于如果处理这些信息(如组装成sql语句),则是由开发人员自己在DAO里完成的.
  FilterSet filterSet =limit.getFilterSet();
  Map filterPropertyMap=filterSet.getPropertyValueMap();
    
// 在本例中, sort 和 filter 相关信息将被传入 DAO,用于拼装sql语句.
// 其实,此时的排序 过滤就和我们以前的传统的查询非常类似:从查询页面取得查询条件,传入DAO.

// RequestUtils.getTotalRowsFromRequest(request);是一个工具类,用来从ECSIDE的列表中取得上次计算出的总行数
// 如果您不希望每次翻页都重新计算总行数,那么建议参考下面几行代码的做法.

int totalRows = RequestUtils.getTotalRowsFromRequest(request);
  if (totalRows < 0) {
// TODO :  userInfoDAO.getUserInfoNumber()为能够取得总行数的方法,请替换为实际的实现。
// 取得记录总条数时,不要忘了把filter作为参数传入,因为要取得的总行数也是要接受条件限制的.
   totalRows = userInfoDAO.getUserInfoNumber(filterPropertyMap);
  }
  
  
  
// DEFAULT_PAGE_SIZE ==0 时, 每页记录数会使用 properties文件内的默认设置
// DEFAULT_PAGE_SIZE <0 时, 每页记录数会等于全部记录数 
  limit.setRowAttributes(totalRows, DEFAULT_PAGE_SIZE);

//取得当前要查询的页面的记录起止行号
// offset表示数据编号的起始号. ORACLE数据库一般是从1开始的,HSQLDB是从0开始,默认是从0开始计数,在这里我们使用从0开始.
  int offset=0;
  int[] rowStartEnd =new int[] { limit.getRowStart() + offset, limit.getRowEnd() + offset };

// TODO :  userInfoDAO.getSomeUserInfo(rowStartEnd[0], rowStartEnd[1])
// 为查询记录的方法,请替换为实际的实现。rowStartEnd[0], rowStartEnd[1]为起止行
// rowStartEnd[0], rowStartEnd[1] 左闭 右开
  List rslist = userInfoDAO.getSomeUserInfo(rowStartEnd[0], rowStartEnd[1],sortValueMap,filterPropertyMap);

request.setAttribute("recordList", rslist);
 
// 字典数据. 一个Map,存放的是  "编号" 到 "显示的文字" 的映射
  request.setAttribute("GENDER_MAP", CommonDictionary.GENDER);
  request.setAttribute("USERROLE_MAP", CommonDictionary.USERROLE);
  
  return mapping.findForward("listPage");
 }
[/code]

其实上面的代码和代码里的注释已经说的比较明白了.

DAO里的代码
[code]
public List getSomeUserInfo(int startRow,int endRow,Map sortValueMap,Map filterPropertyMap){
 StringBuffer bufSql = new StringBuffer();
 int size=endRow-startRow;
 
// 使用传统JDBC时,根据不同条件拼装不同的SQL一向是非常恼人的事情.
// ECSide当然不能够帮助您解决这个问题.
// 再次重申一遍,当翻页 过滤 排序 均基于数据库时,ECSide只是能够帮助开发者在后台更方便的取得操作相关的数据.
// 而如何使用他们,仍然需要开发人员自己来决定.
 
 bufSql.append("SELECT * FROM ");
 
 StringBuffer whereSql = new StringBuffer(" WHERE 1=1 ");
 
 if (filterPropertyMap!=null && !filterPropertyMap.isEmpty()){
// 根据过滤条件进行sql语句的拼装.
 
// 在本例中,只有 USERROLE USERNAME GENDER 是可以进行过滤的.
// 在这里偷下懒,就不用 PreparedStatement 的方式了,而是直接把过滤项拼装进sql语句内.
  String filterProperty;
  String filterValue;
  
  filterProperty="USERROLE";
  filterValue=(String)filterPropertyMap.get(filterProperty);
  if (filterValue!=null){
   whereSql.append(" AND ").append(filterProperty).append(" = '").append(StringEscapeUtils.escapeSql(filterValue)).append("' ");
  }

filterProperty="USERNAME";
  filterValue=(String)filterPropertyMap.get(filterProperty);
  if (filterValue!=null){
   whereSql.append(" AND ").append(filterProperty).append(" like '").append(StringEscapeUtils.escapeSql(filterValue)).append("' ");
  }
  
  filterProperty="GENDER";
  filterValue=(String)filterPropertyMap.get(filterProperty);
  if (filterValue!=null){
   whereSql.append(" AND ").append(filterProperty).append(" = '").append(StringEscapeUtils.escapeSql(filterValue)).append("' ");
  }
 }
 
 if (sortValueMap!=null && !sortValueMap.isEmpty()){
  bufSql.append("( SELECT * FROM USER_INFO  ");
  bufSql.append(whereSql);
  bufSql.append(ECSideUtils.getDefaultSortSQL(sortValueMap));
  bufSql.append(" ) ");
 }else{
  bufSql.append(" USER_INFO ");
  bufSql.append(whereSql);
 }
 
 bufSql.append(" LIMIT ? OFFSET ?");
 
 
 Connection conn=null;
 PreparedStatement pstmt = null;
 ResultSet rest = null;
 List userList=null;
 
 try {
  conn = getConnection();
  pstmt = ConnectionUtils.prepareStatement(conn,bufSql.toString());
  int prarameterIndex=0;
  
  pstmt.setInt(++prarameterIndex, size);
  pstmt.setInt(++prarameterIndex, startRow);
  
  rest = pstmt.executeQuery();
  String[] columnName=getColumnName(rest);
  userList=new ArrayList();
  Map userInfo=null;
  while (rest.next()) {
   userInfo=new HashMap();
   buildRecord(rest,columnName,userInfo);
   userList.add(userInfo);
  }
 } catch (Exception e) {
  LogHandler.errorLog(logger, e);
  userList=null;
 }finally{
  close(rest, pstmt, conn);
 }
 
 return userList;
}

[/code]

这个DAO同样没什么好说的了 非常好理解.

以上就是一个简单的实现,最有参考价值的就是ACTION的写法.

Ecside基于数据库的过滤、分页、排序的更多相关文章

  1. Mybatis分页-利用Mybatis Generator插件生成基于数据库方言的分页语句,统计记录总数 (转)

    众所周知,Mybatis本身没有提供基于数据库方言的分页功能,而是基于JDBC的游标分页,很容易出现性能问题.网上有很多分页的解决方案,不外乎是基于Mybatis本机的插件机制,通过拦截Sql做分页. ...

  2. 基于AngularJS的过滤与排序

    前面了解了AngularJS的使用方法,这里就简单的写个小程序,实现查询过滤以及排序的功能. 本程序中可以了解到: 1 angularjs的过滤器 2 ng-repeat的使用方法 3 控制器的使用 ...

  3. 【AngularJS】—— 6基于AngularJS的过滤与排序

        阅读目录 程序设计分析 代码以及结果 前面了解了AngularJS的使用方法,这里就简单的写个小程序,实现查询过滤以及排序的功能. 本程序中可以了解到: 1 angularjs的过滤器 2 n ...

  4. 基于AngularJS的过滤与排序【转载】

    程序设计分析 首先,如果要是先查询过滤,就要使用到AngularJS中的 过滤器filter 了. 直接在表达式的后面使用管道命令符 | ,按照下面的写法就可以达到一个过滤的效果: {{ person ...

  5. 在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

    背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5中创建GridView>中,我们学习了如何在 ASP.NET MVC 中实现 GridView,类似于 ASP.NET web ...

  6. [转]在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

    本文转自:http://www.cnblogs.com/powertoolsteam/p/MVC5_GridView_2.html 背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5 ...

  7. django-rest-framework 基础四 过滤、排序、分页、异常处理

    django-rest-framework 基础四 过滤.排序.分页.异常处理 目录 django-rest-framework 基础四 过滤.排序.分页.异常处理 1. 过滤 1.1 内置过滤类 1 ...

  8. MixItUp:超炫!基于 CSS3 & jQuery 的过滤和排序插件

    MixItUp 是一款轻量,但功能强大的 jQuery 插件,提供了对分类和有序内容的美丽的动画过滤和排序功能.特别适合用于作品集网站,画廊,图片博客以及任何的分类或有序内容. 它是如何工作的? Mi ...

  9. 分页技巧_改进JSP页面中的公共分页代码_实现分页时可以有自定义的过滤与排序条件

    分页技巧__改进JSP页面中的公共分页代码 自定义过滤条件问题 只有一个url地址不一样写了很多行代码 public>>pageView.jspf添加 分页技巧__实现分页时可以有自定义的 ...

随机推荐

  1. Opencv--HoughCircles源码剖析

    图形可以用一些参数进行表示,标准霍夫变换的原理就是把图像空间转换成参数空间(即霍夫空间),例如霍夫变换的直线检测就是在距离-角度空间内进行检测.圆可以表示成: (x-a)2+(y-b)2=r2     ...

  2. C#中的多线程使用 -- Thread 类详解(转)

    现在C#已经建议摈弃使用 Suspend, Resume 暂停/恢复线程, 也尽量少用 Abort方法中断一个线程. 建议使用线程的同步手段有: Mutex.ManualResetEvent.Auto ...

  3. 理解Java的GC日志

    分析如下GC日志:[GC [PSYoungGen: 9216K->1024K(9216K)] 1246196K->1246220K(1287040K), 0.2398360 secs] [ ...

  4. UTF-8、GB2312都支持的汉字截取函数

    <?php/*Utf-8.gb2312都支持的汉字截取函数cut_str(字符串, 截取长度, 开始长度, 编码);编码默认为 utf-8开始长度默认为 0*/ function cut_str ...

  5. Oracle 表连接方式分析 .

    一 引言 数据仓库技术是目前已知的比较成熟和被广泛采用的解决方案,用于整和电信运营企业内部所有分散的原始业务数据,并通过便捷有效的数据访问手段,可以支持企业内部不同部门,不同需求,不同层次的用户随时获 ...

  6. PHP每日签到及连续签到奖励实现示例

    数据库字段 num 记录已经连续签到次数 times 记录签到的日期 格式年月日 如 20160101 PHP代码如下 <?php //获取今天的日期 $today = date('Ymd'); ...

  7. autofac使用笔记

    在之前的项目中用来解耦的使用的轻型IOC框架是unity,它的使用也是很方便的提供在之前的文章的也提到过它的使用方式,但是使用久了之后发现了它的不足之处就是需要配置xml文件来对应的接口和实现的关系. ...

  8. MySQL应用层传输协议分析

    001.在MySQL应用层传输协议中主要有如下三种类型的数据: 01.整数类型. 02.字符串类型. 03.描述数据包. 002.MySQL应用层传输协议中对整型的说明: 01.固定长度的整型---- ...

  9. Git学习04 --分支管理

    每次commit,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD严格来说不是指向提交,而是指向master ...

  10. Dispatcher.BeginInvoke()方法使用不当导致UI界面卡死的原因分析

    原文:Dispatcher.BeginInvoke()方法使用不当导致UI界面卡死的原因分析 前段时间,公司同事开发了一个小工具,在工具执行过程中,UI界面一直处于卡死状态. 通过阅读代码发现,主要是 ...