Jmesa默认的方式是对所有的数据进行排序与过滤,如果数据太多,对性能肯定会造成影响,这是每个分页都必须处理的问题。Jmesa通过Limit来完成从数据库提取部分数据的中转操作。
见下面代码:
private void addItems(TableFacade tableFacade) {
Limit limit = tableFacade.getLimit();
int rowCount = FillListData.getRowCount();
//获取分面数据前必须先设置数据总数与数据集合
tableFacade.setTotalRows(rowCount);
tableFacade.setItems(FillListData.getData());
this.getContext().getRequest().setAttribute("limit", limit);
this.getContext().getRequest().setAttribute("items",
FillListData.getData());
//代表当前页数据的开始行与结束行位置
int rowStart = limit.getRowSelect().getRowStart();
int rowEnd = limit.getRowSelect().getRowEnd();
System.out.println("rowStart=" + rowStart + " rowEnd=" + rowEnd);
//此处提取过滤的条件
FilterSet filterSet = limit.getFilterSet();
Collection<Filter> filters = filterSet.getFilters();
for (Filter filter : filters) {
String property = filter.getProperty();
String value = filter.getValue();
System.out.println("property="+property+" value="+value);
}
//此处提取过滤的排序方式,如asc,desc等
SortSet sortSet = limit.getSortSet();
Collection<Sort> sorts = sortSet.getSorts();
for (Sort sort : sorts) {
String property = sort.getProperty();
String order = sort.getOrder().toParam();
System.out.println("property="+property+" value="+order);
}
}
JSP代码据说要加上这个:
<jmesa:tableFacade items="${items}" ..... limit="${limit}" >
好像不加也行,暂时还不知道有什么影响。
有了上面代码提供的条件,就可以从数据库中提取相应部分的数据记录了。官方提供了一个很好的例子,使用的是Hibernate的Criteria查询方式:
....
protected void setDataAndLimitVariables(TableFacade tableFacade) {
Limit limit = tableFacade.getLimit();
PresidentFilter presidentFilter = getPresidentFilter(limit);
/*
* Because we are using the State feature (via stateAttr) we can do a check to see if we
* have a complete limit already. See the State feature for more details
*/
if (!limit.isComplete()) {
int totalRows = presidentService.getPresidentsCountWithFilter(presidentFilter);
tableFacade.setTotalRows(totalRows); /*
* Very important to set the totalRow
* before trying to get the
* row start and row end variables.
*/
}
PresidentSort presidentSort = getPresidentSort(limit);
int rowStart = limit.getRowSelect().getRowStart();
int rowEnd = limit.getRowSelect().getRowEnd();
Collection<President> items = presidentService.getPresidentsWithFilterAndSort(presidentFilter, presidentSort, rowStart, rowEnd);
tableFacade.setItems(items); // Do not forget to set the items back on the tableFacade.
}
/**
* A very custom way to filter the items. The PresidentFilter acts as a command for the
* Hibernate criteria object. There are probably many ways to do this, but this is the most
* flexible way I have found. The point is you need to somehow take the Limit information and
* filter the rows.
*
* @param limit The Limit to use.
*/
protected PresidentFilter getPresidentFilter(Limit limit) {
PresidentFilter presidentFilter = new PresidentFilter();
FilterSet filterSet = limit.getFilterSet();
Collection<Filter> filters = filterSet.getFilters();
for (Filter filter : filters) {
String property = filter.getProperty();
String value = filter.getValue();
presidentFilter.addFilter(property, value);
}
return presidentFilter;
}
/**
* A very custom way to sort the items. The PresidentSort acts as a command for the Hibernate
* criteria object. There are probably many ways to do this, but this is the most flexible way I
* have found. The point is you need to somehow take the Limit information and sort the rows.
*
* @param limit The Limit to use.
*/
protected PresidentSort getPresidentSort(Limit limit) {
PresidentSort presidentSort = new PresidentSort();
SortSet sortSet = limit.getSortSet();
Collection<Sort> sorts = sortSet.getSorts();
for (Sort sort : sorts) {
String property = sort.getProperty();
String order = sort.getOrder().toParam();
presidentSort.addSort(property, order);
}
return presidentSort;
}
....
PresidentFilter.java
public class PresidentFilter implements CriteriaCommand {
List<Filter> filters = new ArrayList<Filter>();
public void addFilter(String property, Object value) {
filters.add(new Filter(property, value));
}
public Criteria execute(Criteria criteria) {
for (Filter filter : filters) {
buildCriteria(criteria, filter.getProperty(), filter.getValue());
}
return criteria;
}
private void buildCriteria(Criteria criteria, String property, Object value) {
if (value != null) {
criteria.add(Restrictions.like(property, "%" + value + "%").ignoreCase());
}
}
private static class Filter {
private final String property;
private final Object value;
public Filter(String property, Object value) {
this.property = property;
this.value = value;
}
public String getProperty() {
return property;
}
public Object getValue() {
return value;
}
}
}
public class PresidentSort implements CriteriaCommand {
List<Sort> sorts = new ArrayList<Sort>();
public void addSort(String property, String order) {
sorts.add(new Sort(property, order));
}
public Criteria execute(Criteria criteria) {
for (Sort sort : sorts) {
buildCriteria(criteria, sort.getProperty(), sort.getOrder());
}
return criteria;
}
private void buildCriteria(Criteria criteria, String property, String order) {
if (order.equals(Sort.ASC)) {
criteria.addOrder(Order.asc(property));
} else if (order.equals(Sort.DESC)) {
criteria.addOrder(Order.desc(property));
}
}
private static class Sort {
public final static String ASC = "asc";
public final static String DESC = "desc";
private final String property;
private final String order;
public Sort(String property, String order) {
this.property = property;
this.order = order;
}
public String getProperty() {
return property;
}
public String getOrder() {
return order;
}
}
}
public interface CriteriaCommand {
public Criteria execute(Criteria criteria);
}
service部分的代码:
public Collection<President> getPresidentsWithFilterAndSort(PresidentFilter filter, PresidentSort sort, int rowStart, int rowEnd) {
return presidentDao.getPresidentsWithFilterAndSort(filter, sort, rowStart, rowEnd);
}
dao部分的代码:
public List<President> getPresidentsWithFilterAndSort(final PresidentFilter filter, final PresidentSort sort, final int rowStart, final int rowEnd) {
List applications = (List) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(President.class);
criteria = filter.execute(criteria);
criteria = sort.execute(criteria);
criteria.setFirstResult(rowStart);
criteria.setMaxResults(rowEnd - rowStart);
return criteria.list();
}
});
return applications;
}
这个例子的代码实现思路很清晰,值得借鉴,故把它单独提取出来。到此,数据库分页的问题得到彻底的解决。
分享到:
相关推荐
本文档针对mysql分页之limit慢的问题,使用联合索引在大数据量的情况下优化limit分页的性能
Oracle分页(limit方式的运用)Oracle分页(limit方式的运用)
jmesa源码解读 共五部分 jmesa源码解读一[包结构] jmesa源码解读二[limit包] jmesa源码解读三[core包] jmesa源码解读四[core.filter包] jmesa源码解读五[view包]
【使用limit,offset分页场景时为什么会慢】 在SQL查询中,使用`LIMIT`和`OFFSET`进行分页操作在大数据量的情况下可能会变得极其缓慢。这是因为`OFFSET`需要跳过指定数量的行,而数据库必须读取并忽略这些行,这在...
**语法:** `limit_conn_zone $variable zone=name:size;` **配置段:** `http` 此指令用于定义存储会话状态的内存区域,其中键值为 `$variable` 变量的非空值。`size` 参数表示分配给所有键的共享内存大小。例如...
在SQLite中,`LIMIT`子句是SQL查询语句的一部分,用于限制返回的结果集数量。这个功能对于处理大量数据非常有用,特别是当你只需要查看或处理数据集的一部分时。 `LIMIT`子句的基本语法如下: ```sql SELECT ...
RamTool - TestLimit 是一款专为测试计算机内存性能和稳定性的工具。这款软件的主要功能是填满内存并测试系统的极限,以评估系统在高负载下的表现和崩溃阈值。通过这种方式,用户可以了解电脑在处理大量数据时的能力...
windows系统下内存压力测试工具testlimit.exe
这篇博客文章《mybatis代码生成limit分页修复》可能探讨了在MBG生成的代码中,如何处理分页查询时遇到的问题,特别是与`LIMIT` SQL语句相关的错误。 首先,我们先理解一下`LIMIT`在MySQL中的作用。`LIMIT`用于限制...
limit_access_variable zone=one $limit_access_deny; location / { root html; index index.html index.htm; if ($limit_access_deny) { return 403; } } location /limit_interface { ...
"Limiton权限系统开发实战"是一本专注于讲解如何设计、实现和优化权限系统的教程。权限系统在IT行业中扮演着至关重要的角色,它确保了不同用户只能访问他们被授权的资源和功能,保护了数据安全,促进了合规运营。...
在mysql中使用limit传参的方法,一个简单的实例
C#限制鼠标活动区域,限制鼠标的活动区域,当然也可以解锁
相比之下,LIMIT分页是MySQL数据库内置的分页机制,它在服务器端直接处理分页,只返回所需页面的数据。LIMIT关键字与ORDER BY一起使用,可以实现高效的数据分页。例如,`SELECT * FROM table ORDER BY column LIMIT ...
在Java编程中,有时我们需要对数据库查询结果进行分页显示,传统的MySQL数据库中,我们通常会使用`LIMIT`和`OFFSET`子句来实现这一功能。然而,当数据量庞大时,这种做法可能会导致性能问题,因为`OFFSET`在处理大量...
fatal error C1076: compiler limit : internal heap limit reached; use /Zm to specify a higher limit Generating Code... fatal error C1076: compiler limit : internal heap limit reached; use /Zm to ...
hive报hdfs exceeded directory item limit错误,是由于每次任务失败或者异常退出会造成存在HDFS上的临时目录不自动删除,HDFS目录文件数达到上限,可以脚本清理旧的无用目录解决
《Postfix与Sendmail邮件系统:使用Milter-limit防止用户群发滥用》 在电子邮件系统中,Postfix和Sendmail是两种广泛使用的邮件传输代理(MTA)。它们为组织提供了强大的邮件服务,但同时也面临着滥用的风险,比如...
在描述中提到的问题,是关于CodeIgniter的SQLSRV驱动中的`limit()`函数,这个函数在原版驱动中可能存在一些错误或不适应某些特定场景的情况。 在SQL查询中,`LIMIT`语句用于限制返回结果的数量,这对于分页和优化...
a proof of the central limit theorem For Statistics Inference