در این بخش به چگونگی Pagination با Criteria API و JPA JQL میپردازیم که هر کدام معایب و مزایای خود را دارند
Pagination با JQL و متد های ()setFirstResult و ()setMaxResults :
راحترین راه برای Pagination استفاده از Java Query Language و استفاده از متد های setFirstResult و setMaxResults است
Query query = entityManager.createQuery("From Foo"); int pageNumber = 1; int pageSize = 10; query.setFirstResult((pageNumber-1) * pageSize); query.setMaxResults(pageSize); List <Foo> fooList = query.getResultList();
متد setFirstResult مکانی که از آنجا باید شروع به پردازش رکورد ها کند را مشخص میکند
متد setMaxResults مشخص کننده حداکثر تعداد Entity هایی که در هر نمایش و صفحه بندی باید دریافت شود
یکی دیگر از اطلاعاتی که در pagination نیاز است حداکثر تعداد صفحه هایی است که کاربر میتواند دریافت کند و از این طریق بدست می آید :
ابتدا تعداد کل رکورد ها را بدست می آوریم :
Query queryTotal = entityManager.createQuery ("Select count(f.id) from Foo f"); long countResult = (long)queryTotal.getSingleResult();
سپس بر تعداد نمایش در هر صفحه تقسیم میکنیم ( و اگر جواب 0 چون حداقل یک صفحه برای نبود اطلاعات باید داشته باشیم و یا اعشاری بود با 1 جمع میکنیم که در صفحه آخر تعداد باقی مانده نیز قابل مشاهده باشد ) :
int pageSize = 10; int pageNumber = (int) ((countResult / pageSize) + 1);
Pagination با JQL بر اساس Entity Id :
یکی دیگر از استراتژی های Pagination دریافت کلیه Id های Entity ها و سپس کوئری بر اساس دسته کردن Id های مورد نظر. این روش کنترل بیشتری را به ما میدهد :
Query queryForIds = entityManager.createQuery( "Select f.id from Foo f order by f.lastName"); List<Integer> fooIds = queryForIds.getResultList(); Query query = entityManager.createQuery( "Select f from Foo e where f.id in :ids"); query.setParameter("ids", fooIds.subList(0,10)); List<Foo> fooList = query.getResultList();
Pagination با Criteria API :
int pageSize = 10; CriteriaBuilder criteriaBuilder = entityManager .getCriteriaBuilder(); CriteriaQuery<Foo> criteriaQuery = criteriaBuilder .createQuery(Foo.class); Root<Foo> from = criteriaQuery.from(Foo.class); CriteriaQuery<Foo> select = criteriaQuery.select(from); TypedQuery<Foo> typedQuery = entityManager.createQuery(select); typedQuery.setFirstResult(0); typedQuery.setMaxResults(pageSize); List<Foo> fooList = typedQuery.getResultList();
این روش زمانی که نیاز به کوئری های داینامیک تر و امن تر داریم مفید است
دریافت تعداد Entity ها هم با Criteria API ساده است :
CriteriaQuery<Long> countQuery = criteriaBuilder .createQuery(Long.class); countQuery.select(criteriaBuilder.count( countQuery.from(Foo.class))); Long count = entityManager.createQuery(countQuery) .getSingleResult();
پیاده سازی کامل Pagination با Criteria API :
int pageNumber = 1; int pageSize = 10; CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Long> countQuery = criteriaBuilder .createQuery(Long.class); countQuery.select(criteriaBuilder .count(countQuery.from(Foo.class))); Long count = entityManager.createQuery(countQuery) .getSingleResult(); CriteriaQuery<Foo> criteriaQuery = criteriaBuilder .createQuery(Foo.class); Root<Foo> from = criteriaQuery.from(Foo.class); CriteriaQuery<Foo> select = criteriaQuery.select(from); TypedQuery<Foo> typedQuery = entityManager.createQuery(select); while (pageNumber < count.intValue()) { typedQuery.setFirstResult(pageNumber - 1); typedQuery.setMaxResults(pageSize); System.out.println("Current page: " + typedQuery.getResultList()); pageNumber += pageSize; }