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 개 항목. 합계 : 나는 페이지 당 50 개 항목을 표시하려면 150 개 항목.
당신이 언급 한 바와 같이 수는 정확합니다. 올바르게 병합 된 데이터를 표시 할 수있는 방법을 찾아야합니다. 우리는 당신의 저장소가 유형 중 레코드를 정렬하는 것을 볼 수 있습니다. 당신이 결과를 연결할 경우, 그들은 정렬되지 않습니다.
당신의 예에서, 그 가정 할 수 있습니다 repoA.findAll()
반환 [7,8,9]
및 repoB.findAll()
반환 [1, 100]
, 결과가 [7,8,9,1,100]
올바르게 정렬되지 않습니다를. 당신이 필요로하는 솔루션은 데이터 소스 (데이터베이스)를 UNION 연산자를 지원하는지 여부에 따라 달라집니다
노동 조합을 사용하여
JPA이 할 수없는 (노동 조합의 오퍼레이션) . 데이터베이스가 제공하지만 union
(예 : SQL 또는 MongoDB를) 연산자를 사용하면 정렬 한 후 JPA를 통해 IDS에서 레코드를 가져 오기에 따라 레코드의 ID를 가져 오는 데 사용할 수 있습니다.
어떤 조합 없습니다
데이터베이스가를 제공하지 않는 경우,이 작업을 수행하기 위해, 당신이 50 개 항목로드해야합니다, 세 번째 저장소를 만들어야합니다 repoA
을 고려 aOffset
에서 50 개 항목을 repoB
고려 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
}
}