之前做过很多分页,只是拿别人的模板照抄下来。今天做一个分页的时候自己认真分析了一下,里面问题还挺多的。
业务场景:系统做一个web容器的发布系统,需要有个发布历史的页面。
问题:
1、分页机制的原因
2、一般的实现方式
3、自己考虑的实现方式为什么不行
回答:
1、原因:数据量太多,全部列出来不方便查看,对客户端和服务端的压力也比较大。
比如发布系统用了3年了有几十万条发布记录。一次列出来肯定是不符合逻辑的。
2、一般的实现方式与原理。
写一个pager类,里面有三个属性,分别是start,index和size。
前端传入index和size我们根据sql语句limit的写法,可以知道需要分页需要一个偏移量和一个开始行数的。
所以我们把start作为开始行数,默认设为0.用start=(index-1)*size表示分页之后当前页面需要显示的开始行。
pager的代码如下:
public class Pager {
private int size;
private int index;
private int start = 0;
public Pager(int size, int index) {
this.size = size;
this.index = index;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public int getStart() {
int startIndex = (this.index - 1) * size;//因为limit的表示是从零开始,所以我们这里减一
return startIndex > 0 ? startIndex : start;
}
}
limit用法:select * from tablename limit 开始偏移的行号,一次查询的行数(一次显示多少行)
这里我不仅需要分页处理,而且分页之后还要根据版本信息进行当前页的逆序排序,比如第一页点进去需要将第一行显示为当前版本。
3、自己的实现方式与问题
所以我刚开始的想法是只用limit查出来分页信息,然后再用java的排序对当前的所有信息进行排序。
这样就会出现一个问题:我limit出来的信息是默认排序的,所以,第一次进入的时候就不是最新发布的版本了。
比如我有100条数据,我limit 0,10
结果会是前10条数据的按版本号逆向排序
而我需要的是最后10条数据的按版本号的逆向排序
解决办法:还得用数据库自带的order by 进行排序然后在limit
因为sql语句的执行顺序是:先from再select再order by 再limit,这样就不会有上面的问题了。
这里贴出来sql但是是mybatis下写的sql大概可以表达出一个意思,但是不能直接执行,希望新手还是有一定积累在去翻阅博客,不然看起来头疼不说,还浪费时间。
<select id="selectByEnv" resultMap="BaseResultMap" parameterType="com.mogujie.im.manager.api.entity.WinWebPublishEntity" >
select
<include refid="Base_Column_List" />
from WinWebPublish
<where>
<if test="env != null">AND env = #{env,jdbcType=VARCHAR}</if>
</where>
ORDER BY versions desc
limit #{pager.start},#{pager.size}
</select>