逻辑分页和排序 的思路

        一般分页有分页插件,排序在sql指定字段就好,但是最近我遇到一种情况,就是sql语句比较复杂。。有八十多行,两张表(7w 和 11w)数据不算多,但是sql语句嵌套的有点厉害,我特意试了试,那个sql跑完要花1.3w+秒。。。项目里用那个sql肯定不行,然后就把sql简化了,作为了四个查询单表的sql,这样的话就没有嵌套了,但是这样也导致所有的逻辑业务要在serviceImpl里处理了。。而且还不能用分页插件和指定排序字段。。业务逻辑我就不和大家bb了,说说逻辑分页和排序 的思路。

        首先排序: 

        Collections.sort(underList), Collections有个排序的方法,sort里面放的就是排序字段。另外,还需要让underList字段对应的对象实现Comparable接口,这是一个比较器接口。例如:

public class Undercarriage implements Serializable,Comparable<Undercarriage> 

        该对象就实现了序列化接口和比较器接口两个接口,然后在该对象里面重写它的compareTo方法:

@Override
	public int compareTo(Undercarriage o) {
		//return this.underRate.compareTo(o.underRate);
		if(o.underRate == null){
			o.underRate = 0.0;
		}
		if(this.underRate == null){
			this.underRate = 0.0;
		}
		return o.underRate.compareTo(this.underRate);
	} 

其中那两个if是我为了防止判断的时候出现空指针异常自己加的,return的才是重点,compareTo比较的是其前后的数据,就是排序实现的具体依据,至于排出来的是倒序还是正序,只需要换compareTo前后的对象就好,自己多试试就知道了。

        逻辑分页:

        首先一个page的扩展类肯定是需要的
public class Page {

	// 当前页
	private Integer pageIndex;
	// 每页条数
	private Integer pageSize;
	// 开始记录
	@SuppressWarnings("unused")
	private Integer pageStart;
	// null或者0分页;1:不分页
	private Integer all;
	private String startdate;
	private String enddate;
	// 排序字段
	private String sortField;
	// desc or asc
	private String orderType;
}
        然后,写一个for循环:
    //分页
	Integer size=underList.size();
	Integer pageSize = pvo.getPageSize();
	//页数					
	for (int i = 1; i <= (size%pageSize == 0 ? (size/pageSize) : ((size/pageSize)+1) ); i++) {
		synchronized (key) {
		String key1 = i + "selectUnderRate" + pageSize;
		subList = new ArrayList<>(underList.subList((i - 1) * pageSize, pageSize*i <= size ? pageSize*i:size ));
		redis.setex(key1, 600, SerializeUtil.serialize(Message.success(subList)));
	        }
	}
        其中,我这里的i其实是和pageIndex(当前页)是一个意思的,我这里的意思就是说,把最后得出的数据集合underList按页数和每页放的条数加上我这个接口的方法名作为了key,存到了redis缓存里,这样下次用户再访问的时候,数据就能从缓存中取出从而大大加快查询的效率了。其中,for循环里i的循环条件大家要注意下,我用的三目运算符以保证i最大的数值可以和分的页数相等。然后最后按照他传入的pageIndex和pageSize返回对应的数据:
    Integer i=pvo.getPageIndex();
    subList = new ArrayList<>(underList.subList((i - 1) * pageSize, pageSize*i <= size ? pageSize*i:size ));
        后面记得返回subList的数据就好,之后pageIndex和pageSize没变的话,我们都可以从缓存中拿数据,能加快不少速度。另外我这里所用的截取都是直接三目运算符判断的,大家也可以提取出来。然后,提醒下subList()这个函数截取的数据是集合的索引作为截取标的,并且是左包含右不包含的。
        好了,大致的思路就是这样了,其实为了加快速度,最好把这个接口放到定时任务里去,让他自己按时跑一跑查询数据,  我们全部从缓存里拿取最好。大家想看的的话,可以看我上一篇的定时任务的实现篇。然后这其中有什么不懂得,都可以留言问我。


猜你喜欢

转载自blog.csdn.net/SummerYeSky/article/details/80594894