需求:班级与教师是多对多关系,在后台班级管理需要添加一个接口,传入教师的 id 和 pageable, 返回带分页数据的班级信息。
Page<Klass> pageByTeacher(Long teacherId, Pageable pageable);
一开始打算是在 KlassRepository(继承自 PagingAndSortingRepository)中添加一个类似 findByElementId 的接口,然后直接返回带分页的数据。但是试了几次并不成功, 无论是把 teacher 还是将带 teacher 的 List 传入方法中都失败。
换了一种思路,直接调 TeacherRepository 的 FindById() 方法找到 teacher, 然后返回 teacher 的成员 klassList 就行了。
Teacher teacher = teacherRepository.findById(teacherId).get();
List<Klass> klassList = teacher.getKlassList();
但是光返回 klassList 还不行,需要将它包装成 Page 才行,去官网上查到了一种使用 List 构造 Page 的方法
PageImpl
public PageImpl(List<T> content,
Pageable pageable,
long total)
Constructor of PageImpl.
Parameters:
content – the content of this page, must not be null.
pageable – the paging information, must not be null.
total – the total amount of items available. The total might be adapted considering the length of the content given, if it is going to be the content of the last page. This is in place to mitigate inconsistencies.
参数:content: 要传的 List,不为空 pageable: 分页信息,不为空 total: 可用项的总数。如果是最后一页,考虑到给定内容的长度,total 可以被调整。这是为了缓解不一致性。(这句没懂什么意思),可选
一开始还以为它会自己按照传入的参数分割 List
Page<Klass> klassPage = new PageImpl<Klass>(klassList, pageable, klassList.size());
结果 debug 发现不行,得手动分割,就去网上参考了别人的写法
// 当前页第一条数据在 List 中的位置
int start = (int)pageable.getOffset();
// 当前页最后一条数据在 List 中的位置
int end = (start + pageable.getPageSize()) > klassList.size() ? klassList.size() : (start + pageable.getPageSize());
// 配置分页数据
Page<Klass> klassPage = new PageImpl<Klass>(klassList.subList(start, end), pageable, klassList.size());
debug 查看结果
最后为了增加复用性,改成范型方法:
public <T> Page<T> listConvertToPage(List<T> list, Pageable pageable) {
int start = (int)pageable.getOffset();
int end = (start + pageable.getPageSize()) > list.size() ? list.size() : (start + pageable.getPageSize());
return new PageImpl<T>(list.subList(start, end), pageable, list.size());
}
总结:这样装填出来的 Page 还缺少一些信息,只能满足基本的分页要求。有待改进。