定义“分页数据”类,用于向前端返回分页数据。
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
import java.util.List;
/**
* Created on 2020/5/6 21:45
*
* @author linzihao
* @desc 分页数据
*/
@Data
@Builder
public class Page<T> {
@JsonProperty("total_count")
private Integer totalCount;
private List<T> rows;
public Page(Integer totalCount, List<T> rows) {
this.totalCount = totalCount;
this.rows = rows;
}
public Page() {
}
}
定义Mongodb分页查询工具类。
import com.ligeit.operate.infrastructure.commons.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* MongoDB分页插件,需要结合Spring-data使用.
*
* @author linzihao
**/
public class MongoPageHelper {
private static final int FIRST_PAGE_NUM = 1;
private static String LAST_NAME = "_id";
private final MongoTemplate mongoTemplate;
public MongoPageHelper(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
/**
* 分页查询,直接使用skip-limit来分页,可跳页.
*/
public <T> Page<T> pageQuery(Query query, Sort sort, Class<T> entityClass, Integer pageSize, Integer pageNo) {
return pageQuery(query, sort, entityClass, pageSize, pageNo, mongoTemplate.getCollectionName(entityClass));
}
/**
* 分页查询
*/
public <T> Page<T> pageQuery(Query query, Sort sort, Class<T> entityClass, Integer pageSize, Integer pageNo,String collectionName) {
Assert.hasText(collectionName, "Collection name must not be null or empty!");
Assert.notNull(pageSize, "pageSize must not be null or empty!");
Assert.notNull(pageNo, "pageSize must must not be null or empty!");
long total = mongoTemplate.count(query, entityClass, collectionName);
final int pages = (int) Math.ceil(total / (double) pageSize);
if (pageNo <= 0 || pageNo > pages) {
pageNo = FIRST_PAGE_NUM;
}
int skip = pageSize * (pageNo - 1);
query.skip(skip).limit(pageSize);
if (Objects.nonNull(sort)) {
query.with(sort);
}
final List<T> entityList = mongoTemplate.find(query, entityClass, collectionName);
return new Page<>((int) total, entityList);
}
/**
* 联表分页查询,优化分页查询,根据条件去优化
*
*/
public Page<Map> pageJoinQuery(LookupOperation lookup,Criteria criteria, Sort sort, int pageSize, String lastName, String lastValue, String collectionName) {
return pageJoinQuery(lookup, criteria, sort, pageSize, null, lastName, lastValue, collectionName);
}
/**
* 联表分页查询,直接使用skip-limit来分页,可跳页.
*/
public Page<Map> pageJoinQuery(LookupOperation lookup,Criteria criteria, Sort sort, int pageSize, int pageNo,String collectionName) {
return pageJoinQuery(lookup, criteria, sort, pageSize, pageNo, null, null, collectionName);
}
/**
* 联表分页查询
*/
private Page<Map> pageJoinQuery(LookupOperation lookup,Criteria criteria, Sort sort, Integer pageSize, Integer pageNo,
String lastName, String lastValue, String collectionName) {
//查询总数量
Aggregation aggCount = Aggregation.newAggregation(
lookup,
Aggregation.match(criteria),
Aggregation.count().as("count")
);
AggregationResults<Map> resultCount = mongoTemplate.aggregate(aggCount,collectionName, Map.class);
List<Map> countList = resultCount.getMappedResults();
long total = 0L;
Long skip = null;
if(!CollectionUtils.isEmpty(countList)){
total = Long.parseLong(countList.get(0).get("count").toString());
}
//分页查询
List<AggregationOperation> operations = new ArrayList<>();
operations.add(lookup);
if (StringUtils.isNotBlank(lastName)) {
LAST_NAME = lastName;
}
if (StringUtils.isNotBlank(lastValue)) {
if (pageNo != FIRST_PAGE_NUM) {
criteria.and(LAST_NAME).gt(lastValue);
}
} else {
skip = (long) (pageSize * (pageNo - 1));
}
operations.add(Aggregation.match(criteria));
if (Objects.nonNull(sort)) {
operations.add(Aggregation.sort(sort));
}
if (Objects.nonNull(skip)) {
operations.add(Aggregation.skip(skip));
}
operations.add(Aggregation.limit(pageSize));
Aggregation agg = Aggregation.newAggregation(operations);
AggregationResults<Map> result = mongoTemplate.aggregate(agg,collectionName, Map.class);
List<Map> list = result.getMappedResults();
return new Page<>((int) total, list);
}
}