我有两个类:A,B。对于每个类,我都有一个存储库。 我想在一个表中显示数据(前端,类似于http://embed.plnkr.co/V06RsBy4a6fShwmZcUEF/)。我想要服务器端分页。
List<Object> result = new ArrayList();
result.addAll(repoA.findAll());
result.addAll(repoB.findAll());
public interface repoAPaginationRepository extends PagingAndSortingRepository<A, Long> {
Page<A> findAll(Pageable pageRequest);
}
public interface repoAPaginationRepository extends PagingAndSortingRepository<B, Long> {
Page<B> findAll(Pageable pageRequest);
}
是否足以总结两个存储库中的“计数”? 例: 资料库A:100个项目, 资料库B:50个项目。 总计:150件 我想每页显示50个项目。
答案 0 :(得分:0)
正如您提到的,计数将是正确的。您需要找到一种正确显示合并数据的方法。我们可以看到您的存储库对记录进行排序。但是,如果将结果串联起来,它们将不会排序。
在您的示例中,假设repoA.findAll()
返回[7,8,9]
,而repoB.findAll()
返回[1, 100]
,则结果[7,8,9,1,100]
将不会正确排序。您需要的解决方案取决于您的数据源(数据库)是否支持UNION运算符
JPA无法(union operation)执行此操作。但是,如果您的数据库提供了union
运算符(例如:SQL或mongoDB),则可以使用它根据排序来获取记录的ID,然后通过JPA通过ID来获取记录。
如果您的数据库不提供此功能,则需要创建第三个存储库,它必须考虑repoA
加载aOffset
的50个项目和repoB
的50个项目}考虑一个bOffset
,然后对其中的100个进行排序(合并合并应该很快,您可以在50处停止该算法)。
代码看起来像这样
interface RepoA {
List paginate(int count, int offset, SortCriteria sortCriteria);
}
interface RepoB {
List paginate(int count, int offset, SortCriteria sortCriteria);
}
class RepoAB {
private RepoA repoA;
private repoB repoB;
List paginate (int count, int offset, SortCriteria sortCriteria) {
int aOffset = count == 0 ? 0 : calcAOffset(offset, sortCriteria);
int bOffset = count == 0 ? 0 : offset - aOffset;
return mergeSort(
repoA.paginate(count, aOffset),
repoB.paginate(count, bOffset),
SortCriteria sortCriteria,
50
)
}
List mergeSort(List aList, List bList, SortCriteria sortCriteia, int stopAt) {
...
}
int calcAOffset (int offset, SortCriteria sortCriteria) {
// This implementation can be very heavy, it will count all the records that
// that appeared in the previous pages.
// You can evade this computation by knowing the offset using the last record
// in the previous page.
return paginate(offset, 0, sortCriteria).filter(x => x instanceOf A).length
}
}