有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java分页多个存储库

我有两个班: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个项目


共 (1) 个答案

  1. # 1 楼答案

    正如你提到的,计数是正确的。您需要找到正确显示合并数据的方法。我们可以看到,您的存储库在这些类型中对记录进行了排序。但是如果将结果串联起来,它们将不会被排序

    在您的示例中,假设repoA.findAll()返回[7,8,9]repoB.findAll()返回[1, 100],结果[7,8,9,1,100]将无法正确排序。您需要的解决方案取决于您的数据源(数据库)是否支持UNION运算符

    使用工会

    JPA不能这样做。但是,如果数据库提供了union操作符(例如:SQL或mongoDB),则可以使用它根据排序获取记录的ID,然后通过JPA按ID获取记录

    没有工会

    如果您的数据库没有提供,要做到这一点,您需要创建第三个存储库,它必须从repoA加载50个项目(考虑到aOffset),从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
      }
    }