注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Mr.7

我将骄傲的活在这个大唐盛世

 
 
 

日志

 
 

一个老故事:JAVA解决分页的方式  

2014-01-07 22:59:56|  分类: 挨踢咋活 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

1.没有分页时

没有分页的时候,我们的处理可能是这样的:

public List<Order> QueryDateForUser(User user, Date deliverydate)

{

}

此时返回的只是结果集;通过结果集当然可以知道返回的个数

2.有分页时

没有分页的时候,我们的处理可能是这样的:

// pageNo - 指定页

// pageSize - 每页大小

public Page<Order> QueryDateForUser_Page(User user, Date deliverydate, int pageNo, int pageSize)

{

}

此时返回的是指定页的信息Page。Page中应该包括当前页结果集List<Order>;还包括分页情况:总条数;以及之前的分页参数:当前页数和每页条数。

3.兼容有和没有分页的情况

有和没有分页的时候,我们希望统一处理。可能的解决方法是这样的:

public List<Order> QueryDateForUser(User user, Date deliverydate, Page page)

{

}

page信息由使用者传递过去。

  • 如果page为null,则是不分页的情况;将返回所有的结果集。
  • 如果page有值,page是输入输出参数
  • 输入参数时,page中应该先确定分页参数:每页条数,当前页;
  • 输出参数时,page中应该包含记录总数;有了记录总数,可以知道可以分多少页等其它分页信息
  • 返回值表示当前页内的结果集

这样,避免前面两种返回值不同的情况。约定返回值相同,可以让用户在进行分页与否切换时,改动较小。而从实现角度来看,从没有分页到有分页的切换,实际上就是在原来的代码中,插入一个分页处理。插入的逻辑如下面部分:

public List<Order> QueryDateForUser(User user, Date deliverydate, Page page)
{
List<Order> rtn = null;
Query q = CreateNameQuery("QueryDateForUser")
.setParameter(1, user)
.setParameter(2, deliverydate);

//-设置分页信息-
if(null!=page)
{
long totalCount = getCountFromNameQuery("QueryDateForUser", user, deliverydate);
page.setTotalCount(totalCount);
SetQueryPage(q, page);
}


rtn = (List<Order>) q.getResultList();
return rtn;
}

分页处理,在JPA中其实很简单,仅仅是设置页的起始值setFirstResult(注意从0开始);以及页的记录条数setMaxResults(注意:如果从起始值到最后条数小于页条数,会自动截短)

Query SetQueryPage(Query query, Page page)
{
if(null!=page)
{
query.setFirstResult(page.getPageNo()*page.getPageSize());
query.setMaxResults(page.getPageSize());
}
return query;
}

全部问题都落在总条数这个问题上了。

4.如何获取总条数

简单的方法是,两个JPQL。一定有一个Select * 的JPQL,作为结果集返回。另一个再写一个Select count(*),表示个数而已嘛!

这种方法唯一的麻烦就是一些语句要写两遍。如下:

@Entity
@Table(name = "orders")
@NamedQueries ({
@NamedQuery (name= "QueryForUser" , query= "FROM Order WHERE user=?1 ORDER BY deliverydate DESC" ),
@NamedQuery (name= "QueryDateForUser" , query= "FROM Order WHERE user=?1 AND deliverydate =?2 ORDER BY deliverydate DESC"),
@NamedQuery (name= "QueryOrderNoForUser" , query= "FROM Order WHERE user=?1 AND orderNo LIKE CONCAT('%',?2,'%') ORDER BY deliverydate DESC"),
@NamedQuery (name= "QueryDateOrderNoForUser" , query= "FROM Order WHERE user=?1 AND deliverydate =?2 AND orderNo LIKE CONCAT('%',?3,'%') ORDER BY deliverydate DESC"),
@NamedQuery (name= "GetRecentOrder" , query= "FROM Order WHERE user=?1 AND deliverydate between ?2 AND ?3 ORDER BY deliverydate")
})
public class Order implements Serializable
{

}

如何省点配置,自动获取NamedQuery对应的query呢。

最开始的方法总是想从JPA的方法入手。后来发现还是回归原始,直接从入手。如下:

String GetJpqlFromNamedQuery(Class<T> _entityClass, String queryname)
{
String query = "";

Annotation an[] = _entityClass.getAnnotations();
for(int i=0;i<an.length; i++)
{
if(an[i].annotationType()==NamedQueries.class)
{
NamedQueries ns = (NamedQueries)an[i];

for(NamedQuery n : ns.value())
{
if(n.name().equals(queryname))
query = n.query();
}

break;
}
else if(an[i].annotationType()==NamedQuery.class)
{
NamedQuery n = (NamedQuery)an[i];
if(n.name().equals(queryname))
query = n.query();
break;
}
}

return query;
}

至于有了query,拼凑SELECT COUNT 就很简单了。

5.PageTag分页参数处理

只要知道每页个数,当前页,总记录数。构造类似分页就很简单了。分页包括:总条数,当前记录数,首页尾页,上一页,下一页,页码,跳转!

  评论这张
 
阅读(461)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018