交代一下前言,資料是redis中查詢
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLwEEVOpXVU5UeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL0kjM1UjN0gDMyIzNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
140,193,88,117 格式大概是這樣。 需要切割為long類型的list數組。需要手動計算分頁,去mongodb中查詢資料。
這裡我用的手動計算分頁的是 hutool 工具包
import cn.hutool.core.util.PageUtil; 裡面挺多實用的工具
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> </dependency>
int[] ints = PageUtil.transToStartEnd(page - 1, pageSize);
傳入頁碼,和資料條數,計算資料起始位置
将頁數和每頁條目數轉換為開始位置和結束位置 此方法用于包括結束位置的分頁方法 例如:
頁碼:0,每頁10 =》 [0, 10]
頁碼:1,每頁10 =》 [10, 20]
……
當setFirstPageNo(int)設定為1時:
頁碼:1,每頁10 =》 [0, 10]
頁碼:2,每頁10 =》 [10, 20]
……
Params:
pageNo – 頁碼(從0計數)
pageSize – 每頁條目數
Returns:
第一個數為開始位置,第二個數為結束位置
int[] ints = PageUtil.transToStartEnd(page - 1, pageSize);
通過工具傳回起始頁碼。
//根據起點, 和 終點, 截取到中間的vid 查詢
List<Long> vids = split.stream().skip(ints[0]).limit(ints[1]).map(Long::valueOf).collect(Collectors.toList());
通過stream 流。搭配分頁工具。 實作手動分頁。 .map(Long::valueOf) 将string 轉為Long 類型
collect(Collectors.toList()); 收集到分頁之後的資料。如果起始位置超出list集合的size 不為報錯。結束位置超出list的size 不會出錯。 但是size為0 。 if (vids.size() > 0) { 判斷一下。進行下面的步驟。
其實羅裡吧嗦一大堆,代碼就兩行。
// 将頁數和每頁條目數轉換為開始位置和結束位置 此方法用于包括結束位置的分頁方法 例如: 頁碼:0,每頁10 =》 [0, 10]
int[] ints = PageUtil.transToStartEnd(page - 1, pageSize);
//根據起點, 和 終點, 截取到中間的vid 查詢
List<Long> vids = split.stream().skip(ints[0]).limit(ints[1]).map(Long::valueOf).collect(Collectors.toList());
這裡放一下這個方法的全部代碼吧。
/**
* 分頁查詢小視訊清單,按照時間倒序排序 優先查詢推薦的視訊,如果沒有推薦的視訊或已經查詢完成。再查詢預設的
*
* @param userId 使用者id
* @param page 第幾頁
* @param pageSize 每頁幾條
* @return PageInfo<Video>
*/
@Override
public PageInfo<Video> queryVideoList(Long userId, Integer page, Integer pageSize) {
//傳回的結果集
PageInfo<Video> pageInfo = new PageInfo<>();
pageInfo.setPageNum(page);
pageInfo.setPageSize(pageSize);
//小視訊推薦 redis key
String redisKey = RedisKeyUtils.getVIDEOKEY(userId);
//redis推薦視訊vid 140,193,88,117, vid
String redisValue = redisTemplate.opsForValue().get(redisKey);
//如果redis中推薦的視訊id不為空
int recommendCount = 0;
//如果redis 推薦視訊不為空
if (StringUtils.isNotEmpty(redisValue)) {
//分割key
List<String> split = StrUtil.split(redisValue, ',');
//用于查找預設視訊時,跳過的頁數計算
recommendCount = split.size();
// 将頁數和每頁條目數轉換為開始位置和結束位置 此方法用于包括結束位置的分頁方法 例如: 頁碼:0,每頁10 =》 [0, 10]
int[] ints = PageUtil.transToStartEnd(page - 1, pageSize);
//根據起點, 和 終點, 截取到中間的vid 查詢
List<Long> vids = split.stream().skip(ints[0]).limit(ints[1]).map(Long::valueOf).collect(Collectors.toList());
//如果推薦視訊vid 不為空,查詢推薦視訊
if (vids.size() > 0) {
Query query = Query.query(Criteria.where("vid").in(vids));
List<Video> videos = mongoTemplate.find(query, Video.class);
pageInfo.setRecords(videos);
return pageInfo;
}
}
//解決為了讓預設視訊從0開始,如果之前推薦視訊已經刷到第四頁。這裡需要減去4,包裝從0頁往下查詢
int totalPage = PageUtil.totalPage(recommendCount, pageSize);
//如果推薦視訊為空,或查詢完畢,查詢傳回預設的視訊清單
PageRequest pageRequest = PageRequest.of(page - totalPage - 1, pageSize,
Sort.by(Sort.Order.desc("created")));
Query query = new Query();
query.with(pageRequest);
List<Video> videos = mongoTemplate.find(query, Video.class);
pageInfo.setRecords(videos);
return pageInfo;
}