锁定老帖子 主题:后台分页思路
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (14)
|
|
---|---|
作者 | 正文 |
发表时间:2011-04-11
wuhuajun 写道 楼主的意思是全部加在到内存再分页,不然怎么会把内存吃光。。。
不是全部加到内存啊。我用的是mysql,select xxxxx from talbe where whereSql limit ?,? 难道这样会全部加到内存里分页吗? |
|
返回顶楼 | |
发表时间:2011-04-11
比较理想的分页方式是用几条记录就到数据库查几条
|
|
返回顶楼 | |
发表时间:2011-04-11
huqingwei311 写道 比较理想的分页方式是用几条记录就到数据库查几条
难道我现在的方法不是吗? |
|
返回顶楼 | |
发表时间:2011-04-11
parwin2 写道 这方法貌似不可取,不能全部结果集全部列出,拿出该页显示的条数即可。否则对于数据比较多的时候速度慢、导致服务器崩溃,多并发的时候那可是严重的问题。
都已经拿出来分好页了,下次直接缓存取不就快了。 我觉得这里的问题不在性能上。问题是万一每页size变了咋办,也不好缓存,每次都去db拉列表,比较杯具。 |
|
返回顶楼 | |
发表时间:2011-04-11
分页这个问题,如果你要自实现,我有段代码可以供你参考,这个是几年前参考Hibernate官方的一篇文章修改的,应该还是可以用的。
public interface Page<T> { /** * @return 是否是首页(第一页),第一页页码为1 */ public boolean isFirst(); /** * @return 是否是最后一页 */ public boolean isLast(); /** * @return 是否有下一页 */ public boolean hasNext(); /** * @return 是否有上一页 */ public boolean hasPrevious(); /** * @return 当前页的数据内容 */ public List<T> getThisPageElements(); /** * @return 数据总的条目数量 */ public int getTotalNumberOfElements(); /** * @return 当前页的首条数据的行编码 */ public int getFirstElementNumber(); /** * @return 当前页的末条数据的行编码 */ public int getLastElementNumber(); /** * @return 当前页编码 */ public int getPageNumber(); /** * @return 下一页编码 */ public int getNextPageNumber(); /** * @return 上一页编码 */ public int getPreviousPageNumber(); /** * @return 获取最后一页页码,也就是总页数 */ public int getLastPageNumber(); /** * @return 每一页显示的条目数 */ public int getPageSize(); } 基于Hibernate的实现: public class HibernatePage<T> implements Page<T> { private List<T> elements; private int pageSize; private int pageNumber; private int totalElements = 0; /** * 构建HibernatePage对象,完成Hibernate的Query数据的分页处理 * * @param query * Hibernate的Query对象 * @param pageNumber * 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。 * 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。 * 这两种情况将重新更改当前页的页码,为最后一页编码。 * @param pageSize * 每一页显示的条目数 */ public HibernatePage(Query query, int pageNumber, int pageSize) { this.pageNumber = pageNumber; this.pageSize = pageSize; try { ScrollableResults scrollableResults = query.scroll(); // get the total elements number scrollableResults.last(); this.totalElements = scrollableResults.getRowNumber(); if (Integer.MAX_VALUE == this.pageNumber || this.pageNumber > getLastPageNumber()) // last page { this.pageNumber = getLastPageNumber(); } elements = query.setFirstResult( (this.pageNumber - 1) * this.pageSize).setMaxResults( this.pageSize + 1).list(); } catch (HibernateException e) { throw new RuntimeException(e); } } public boolean isFirst() { return getPageNumber() == 1; } public boolean isLast() { return getPageNumber() >= getLastPageNumber(); } public boolean hasNext() { return getLastPageNumber() > getPageNumber(); } public boolean hasPrevious() { return getPageNumber() > 1; } public int getLastPageNumber() { return totalElements % this.pageSize == 0 ? totalElements / this.pageSize : totalElements / this.pageSize + 1; } /** * 返回List类型数据 * * @return List数据源 */ public List<T> getThisPageElements() { return elements; } public int getTotalNumberOfElements() { return totalElements; } public int getFirstElementNumber() { return (getPageNumber() - 1) * getPageSize() + 1; } public int getLastElementNumber() { int fullPage = getFirstElementNumber() + getPageSize() - 1; return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements() : fullPage; } public int getNextPageNumber() { return getPageNumber() + 1; } public int getPreviousPageNumber() { return getPageNumber() - 1; } public int getPageSize() { return pageSize; } public int getPageNumber() { return pageNumber; } } 基于JPA的实现: public class JPAPage<T> implements Page<T> { private List<T> elements; private Integer pageSize; private Integer pageNumber; private Integer totalElements = 0; /** * 构建JPAPage对象,完成JPAPage的Query数据的分页处理 * * @param countQuery * Hibernate的查询总数的Query对象 * @param pageNumber * 当前页编码 * @param pageSize * 每一页显示的条目数 * @param dataQuery * Hibernate的查询结果的Query对象 */ public JPAPage(Query countQuery, int pageNumber, int pageSize, Query dataQuery) { // 设置 this.pageSize = pageSize; this.pageNumber = pageNumber; // 验证 if (this.pageNumber < 1) { this.pageNumber = 1; } if (Integer.MAX_VALUE == this.pageNumber || this.pageNumber > getLastPageNumber()) // last page { this.pageNumber = getLastPageNumber(); } // 注入数据 try { Object obj = countQuery.getSingleResult(); if (obj != null && obj instanceof Long) { this.totalElements = ((Long) obj).intValue(); } else { throw new NumberFormatException("[countQuery is error.]"); } elements = dataQuery.setFirstResult( (this.pageNumber - 1) * this.pageSize).setMaxResults( this.pageSize + 1).getResultList(); } catch (Exception e) { throw new RuntimeException(e); } } public boolean isFirst() { return getPageNumber() == 1; } public boolean isLast() { return getPageNumber() >= getLastPageNumber(); } public boolean hasNext() { return getLastPageNumber() > getPageNumber(); } public boolean hasPrevious() { return getPageNumber() > 1; } public int getLastPageNumber() { return totalElements % this.pageSize == 0 ? totalElements / this.pageSize : totalElements / this.pageSize + 1; } /** * 返回List类型数据 * * @return List数据源 */ public List<T> getThisPageElements() { return elements; } public int getTotalNumberOfElements() { return totalElements; } public int getFirstElementNumber() { return (getPageNumber() - 1) * getPageSize() + 1; } public int getLastElementNumber() { int fullPage = getFirstElementNumber() + getPageSize() - 1; return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements() : fullPage; } public int getNextPageNumber() { return getPageNumber() + 1; } public int getPreviousPageNumber() { return getPageNumber() - 1; } public int getPageSize() { return pageSize; } public int getPageNumber() { return pageNumber; } } 同样,基于JDBC的实现或者其他什么数据结构查询的实现都很简单。使用Freemarker/Velocity分页宏编写也很容易。 这个分页虽然粗糙,但是一般的应用足够了,不过在排序方面还有待改进。 |
|
返回顶楼 | |
发表时间:2011-04-11
想问一下, select * from table where in(ids),其中IDs为500+,这样的需求有没有好的分页方法
|
|
返回顶楼 | |
发表时间:2011-04-11
一般分页最后都是静态页面,哪有那么多的查询。如果数据是实时变化的,那么后台在一定时间内利用freemarker等模板技术自动静态话,减少查询。
|
|
返回顶楼 | |
发表时间:2011-04-11
看来楼主描述不清楚啊~ 都认为是一次性取出数据了~
|
|
返回顶楼 | |
发表时间:2011-04-11
huangfoxAgain 写道 看来楼主描述不清楚啊~ 都认为是一次性取出数据了~
是啊,大家都没搞清楚,就批判了 |
|
返回顶楼 | |
发表时间:2011-04-11
把数据的标识字段查询出来。然后再内存分页,然后在按照分页再查询具体的数据。
|
|
返回顶楼 | |