Как вы упомянули, счет будет правильным.вам нужно найти способ правильно отобразить объединенные данные.Мы видим, что ваши репозитории сортируют записи среди этих типов.Но если вы объедините результаты, они не будут отсортированы.
В вашем примере предположим, что repoA.findAll()
return [7,8,9]
и repoB.findAll()
return [1, 100]
, результат [7,8,9,1,100]
не будетотсортировано правильно.Решение, которое вам нужно, зависит от того, поддерживает ли ваш источник данных (База данных) оператор UNION или нет
Использование объединений
JPA не может сделать это (операция объединения) .Но если в вашей базе данных есть оператор union
(например, SQL или mongoDB), вы можете использовать его для извлечения идентификаторов записей в соответствии с сортировкой, а затем извлекать записи по идентификаторам через JPA.
Нет объединений
Если ваша база данных не предоставляет, для этого вам потребуется создать третий репозиторий, он должен загрузить 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
}
}