一般分頁有分頁插件,排序在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前後的對象就好,自己多試試就知道了。
邏輯分頁:
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()這個函數截取的數據是集合的索引作爲截取標的,並且是左包含右不包含的。