简体   繁体   English

分页多个存储库

[英]Pagination multiple repositories

I have two classess: A, B. For each class I have repository. 我有两个classess:A,B。对于每个类我都有存储库。 I want display data in one table (frontend, something similiar to: http://embed.plnkr.co/V06RsBy4a6fShwmZcUEF/ ). 我想在一个表中显示数据(前端,类似于: http//embed.plnkr.co/V06RsBy4a6fShwmZcUEF/ )。 I want have server side pagination. 我想要服务器端分页。

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);
}

Is it enough to sum up the "count" from both repositories? 是否足以总结两个存储库的“计数”? Example: Repository A: 100 items, Repository B: 50 items. 示例:存储库A:100个项目,存储库B:50个项目。 Sum: 150 items I want display 50 items per page. 总和:我想要的150件商品每页显示50件商品。

As you mentioned the count will be correct. 如你所说,计数是正确的。 you need to find a way to display the merged data correctly. 您需要找到一种正确显示合并数据的方法。 We can see that your repositories sorts the records among there types. 我们可以看到您的存储库对这些类型中的记录进行排序。 But if you concatenate the results, they will not be sorted. 但如果你连接结果,它们将不会被排序。

In your example, lets suppose that repoA.findAll() return [7,8,9] and repoB.findAll() return [1, 100] , the result [7,8,9,1,100] will not be sorted correctly. 在您的示例中,假设repoA.findAll()返回[7,8,9]并且repoB.findAll()返回[1, 100] ,结果[7,8,9,1,100]将无法正确排序。 The solution you need depends on whether your data source (Database) supports an UNION operator or not 您需要的解决方案取决于您的数据源(数据库)是否支持UNION运算符

Using unions 使用工会

JPA can not do this (union operation) . JPA不能这样做(联合操作) But if your database provides an union operator (for example: SQL or mongoDB) you can use it to fetch the ids of the records according to the sort then fetch the records by ids through JPA. 但是,如果您的数据库提供了一个union运算符(例如:SQL或mongoDB),您可以使用它来根据排序获取记录的ID,然后通过JPA通过ID获取记录。

No unions 没有工会

If your database does not provide the, to do this, you will need to create a third repository, it must load 50 items from repoA considering an aOffset and 50 items from repoB considering a bOffset , then sort the 100 of them (it should be fast with merge sort and you can stop the algorithm at 50). 如果您的数据库没有提供,要做到这一点,您将需要创建第三个存储库,它必须从repoA加载50个项目考虑aOffset和50个来自repoB项目考虑一个bOffset ,然后对其中的100个进行排序(它应该是快速进行合并排序,您可以在50)停止算法。

The code will look something like this 代码看起来像这样

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
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM