若依自带的分页插件 pagehelper,在查询数据是一对一的时候是没有任何问题,但是当遇到一对多的时候,分页就会失效。解决办法,自己写分页,先把主表一对一的数据查出来,再通过stream流来处理。
1 封装返回数据的工具类
package com.ruoyi.util;
import java.util.List;
/**
* 封装返回分页数据
*
*/
public class QueryResult<T> {
// 总条数
private Integer totals;
// 返回的数据
private List<T> data;
public QueryResult() {
super();
}
public QueryResult(Integer totals, List<T> data) {
super();
this.totals = totals;
this.data = data;
}
public Integer getTotals() {
return totals;
}
public void setTotals(Integer totals) {
this.totals = totals;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}
pagehelper分页插件官网给出了以下几种调用方式:
//第一种,RowBounds方式的调用
List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));
//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
//第三种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.offsetPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
//第四种,参数方法调用
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
List<Country> selectByPageNumSize(
@Param("user") User user,
@Param("pageNum") int pageNum,
@Param("pageSize") int pageSize);
}
//配置supportMethodsArguments=true
//在代码中直接调用:
List<Country> list = countryMapper.selectByPageNumSize(user, 1, 10);
//第五种,参数对象
//如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
//有如下 User 对象
public class User {
//其他fields
//下面两个参数名和 params 配置的名字一致
private Integer pageNum;
private Integer pageSize;
}
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
List<Country> selectByPageNumSize(User user);
}
//当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页
List<Country> list = countryMapper.selectByPageNumSize(user);
//第六种,ISelect 接口方式
//jdk6,7用法,创建接口
Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectGroupBy();
}
});
//jdk8 lambda用法
Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(()-> countryMapper.selectGroupBy());
//也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectGroupBy();
}
});
//对应的lambda用法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> countryMapper.selectGroupBy());
//count查询,返回一个查询语句的count数
long total = PageHelper.count(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectLike(country);
}
});
//lambda
total = PageHelper.count(()->countryMapper.selectLike(country));
我们这里采用的是第六种 jdk8的lambda用法
3 service层代码 处理数据
public QueryResult<QuestionVo> getList(QuestionQuery query) {
int num = questionQuery.getNum();
int size = questionQuery.getSize();
PageInfo<Question> pageInfo = PageHelper.startPage(num, size)
.doSelectPageInfo(() -> questionMapper.getQuestionList(query) );
//获取分页总条数
int total = (int) pageInfo.getTotal();
List<Question> list = pageInfo.getList();
List<Long> questionIdList = list.stream().map(Question::getQuestionId).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(questionIdList)) {
List<QuestionOption> questionOptionList = questionOptionMapper.getOptions(questionIdList);
Map<Long, List<QuestionOption>> map = questionOptionList.stream().collect(Collectors.groupingBy(DtQuestionOption::getQuestionId));
list.forEach(questionVo -> questionVo.setOptions(map.get(questionVo.getQuestionId())));
}
return new QueryResult<>(total, list);
}
写完才发现,其实用若依的框架也可以,不用pageHelper,先把一对一的数据查出来,再通过一对多的数据进行关联起来就行。