[英]Java how to transform List<Object> to Page from JPA Paggination
我對來自 Jpa 存儲庫的自定義搜索方法有疑問。 我將此方法實施到自定義 serach,在此方法中,我有來自我的 SQL 基礎的列表,我嘗試將其從 JPA 轉換為頁面object 這只是分頁的錯覺,因為在郵遞員/互聯網瀏覽器中,我看到列表中的所有元素,當我更改端點中的頁面和大小值時,什么都沒有改變。 有人知道如何幫助嗎?
GitHub 項目: https://github.com/s0bieskii/DemoCarRental
我的端點來自 Controller:
@GetMapping("/find")
ResponseEntity<Page<CarDTO>> readAllCarsFiltered(@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "5") int size,
Pageable pageable,
@RequestParam(required = false) String brand,
@RequestParam(required = false) String model,
@RequestParam(required = false) String type,
@RequestParam(required = false) Integer registrationYear,
@RequestParam(required = false) String color,
@RequestParam(required = false) String fuel,
@RequestParam(required = false) String transmission,
@RequestParam(required = false) String doors,
@RequestParam(required = false, defaultValue = "9999999999") double price) {
return ResponseEntity.ok(carService.customerSearch(pageable,
brand, model, type, registrationYear, color, fuel, transmission, doors, price));
}
我的服務
public Page<CarDTO> customerSearch(Pageable pageable, String brand, String model, String type, Integer registrationNumber, String color,
String fuel, String transmission, String doors, double price){
return carRepository.search(pageable, brand, model, type, registrationNumber, color, fuel, transmission, doors, price)
.map(car -> carMapper.carToDto(car));
}
我來自 RepositoryImplementation 的自定義搜索方法
@Override
public Page<Car> search(Pageable pageable, String brand, String model, String type, Integer registrationYear, String color,
String fuel, String transmission, String doors, double price) {
int var = 0;
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Car> query = cb.createQuery(Car.class);
Root<Car> car = query.from(Car.class);
query.select(car);
Predicate predicate = cb.greaterThan(car.get("id"), var);
if (brand != null) predicate = cb.and(predicate, cb.equal(car.get("brand"), brand));
if (model != null) predicate = cb.and(predicate, cb.equal(car.get("model"), model));
if (type != null) predicate = cb.and(predicate, cb.equal(car.get("type"), type));
if (registrationYear != null)
predicate = cb.and(predicate, cb.equal(car.get("registrationNumber"), registrationYear));
if (color != null) predicate = cb.and(predicate, cb.equal(car.get("color"), color));
if (fuel != null) predicate = cb.and(predicate, cb.equal(car.get("fuel"), Fuel.stringToFuelEnum(fuel)));
if (transmission != null)
predicate = cb.and(predicate, cb.equal(car.get("transmission"), Transmission.stringToTransmissionEnum(transmission)));
if (doors != null) predicate = cb.and(predicate, cb.equal(car.get("doors"), doors));
if (price != 0) predicate = cb.and(predicate, cb.lessThan(car.get("price"), price));
//predicate = cb.and(predicate, cb.equal(car.get("available"), available));
List<Car> carList=entityManager.createQuery(query.where(predicate)).getResultList();
return new PageImpl<Car>(carList, pageable,carList.size());
}
}
當您執行自定義查詢並希望使用 Pageable 時,您可以實現一個邏輯來為您的結果列表創建分頁。 在你的情況下,你沒有這樣做,所以它可能(你說它不起作用,但沒有說什么不起作用,所以我只能猜測)只是返回整個結果列表而不應用分頁。
一個簡單的解決方案是使用sublist
並將該操作的結果用作PageImpl
的參數。 大問題是您仍然在后台從數據庫中獲取整個結果列表,這會產生不必要的開銷。
您還可以使用調整您的查詢
em.createQuery(query.where(predicate))
.setFirstResult(offset)
.setMaxResults(limit)
.getResultList()
現在分頁是在數據庫中完成的,這要好得多。
或者您可以省去一些麻煩並使用 Springs Specification
接口,而不是創建自己的搜索方法。
首先,您的CarRepository
需要擴展JpaSpecificationExecutor
。 現在 spring 將為您的存儲庫生成一個findAll(Specification, Pageable)
方法。
第二步是創建您的搜索規范:
public class SearchSpecification implements Specification<Car> {
private final String brand;
private final String model
private final String type
private final Integer registrationYear
private final String color
private final String fuel
private final String transmission
private final String doors
private final double price
// constructor & maybe getter
public Predicate toPredicate(Root<Car> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
// Create your search predicate
}
}
現在您可以簡單地調用carRepository.findAll(new SearchSpecification (/* parameters */), pageable);
spring 為您進行分頁。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.