邏輯分頁和排序 的思路

        一般分頁有分頁插件,排序在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()這個函數截取的數據是集合的索引作爲截取標的,並且是左包含右不包含的。
        好了,大致的思路就是這樣了,其實爲了加快速度,最好把這個接口放到定時任務裏去,讓他自己按時跑一跑查詢數據,  我們全部從緩存裏拿取最好。大家想看的的話,可以看我上一篇的定時任務的實現篇。然後這其中有什麼不懂得,都可以留言問我。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章