Skip to content

Commit 589c175

Browse files
author
jefffischer
committed
BroadleafCommerce/QA#1723 - Add a more efficient paging technique that utilizes last id and page size and omits offset
1 parent e980e15 commit 589c175

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/catalog/dao/ProductDao.java

+18-3
Original file line numberDiff line numberDiff line change
@@ -271,15 +271,30 @@ public interface ProductDao {
271271
*
272272
* It will fetch results in pages. For example, if page = 3 and pageSize = 25, this method would
273273
* return rows 75-99 from the database.
274-
*
274+
*
275+
* When possible, it is suggested to use {@link #readAllActiveProducts(Integer, Long)} instead for performance.
276+
*
275277
* @param page - the number of the page to get (0 indexed)
276278
* @param pageSize - the number of results per page
277279
* @return a list of active products for the given page
278280
*/
279281
public List<Product> readAllActiveProducts(int page, int pageSize);
280282

281283
/**
282-
* @deprecated Use {@link #readAllActiveProducts(page, pageSize)}
284+
* Reads all products from the database that are currently active. This method utilizes efficient
285+
* paging to retrieve a subset of records. This approach does not use an offset technique (like {@link #readAllActiveProducts(int, int)},
286+
* but rather limits the retrieved records to those greater than the given id and returns a max results of pageSize. This
287+
* is more efficient that using an offset, since the database will not have to retrieve all the records from the beginning
288+
* of the table and trim the offset.
289+
*
290+
* @param pageSize the number of results per page
291+
* @param lastId the last id from the previous page - can be null if this is the first page request
292+
* @return a list of active products for the given page
293+
*/
294+
List<Product> readAllActiveProducts(Integer pageSize, Long lastId);
295+
296+
/**
297+
* @deprecated Use {@link #readAllActiveProducts(int, int)}
283298
*
284299
* @param page - the number of the page to get (0 indexed)
285300
* @param pageSize - the number of results per page
@@ -297,7 +312,7 @@ public interface ProductDao {
297312
public Long readCountAllActiveProducts();
298313

299314
/**
300-
* @deprecated {@link #readActiveProductCount()}
315+
* @deprecated {@link #readCountAllActiveProducts()}
301316
*
302317
* @param currentDate
303318
* @return the number of currently active products

core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/catalog/dao/ProductDaoImpl.java

+27-5
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,12 @@ public List<Product> readAllActiveProducts(int page, int pageSize) {
541541
Date currentDate = DateUtil.getCurrentDateAfterFactoringInDateResolution(cachedDate, currentDateResolution);
542542
return readAllActiveProductsInternal(page, pageSize, currentDate);
543543
}
544+
545+
@Override
546+
public List<Product> readAllActiveProducts(Integer pageSize, Long lastId) {
547+
Date currentDate = DateUtil.getCurrentDateAfterFactoringInDateResolution(cachedDate, currentDateResolution);
548+
return readAllActiveProductsInternal(pageSize, currentDate, lastId);
549+
}
544550

545551
@Override
546552
@Deprecated
@@ -557,6 +563,15 @@ protected List<Product> readAllActiveProductsInternal(int page, int pageSize, Da
557563

558564
return query.setFirstResult(firstResult).setMaxResults(pageSize).getResultList();
559565
}
566+
567+
protected List<Product> readAllActiveProductsInternal(Integer pageSize, Date currentDate, Long lastId) {
568+
CriteriaQuery<Product> criteria = getCriteriaForActiveProducts(currentDate, lastId);
569+
TypedQuery<Product> query = em.createQuery(criteria);
570+
query.setHint(QueryHints.HINT_CACHEABLE, true);
571+
query.setHint(QueryHints.HINT_CACHE_REGION, "query.Catalog");
572+
573+
return query.setMaxResults(pageSize).getResultList();
574+
}
560575

561576
@Override
562577
public List<Product> readAllActiveProducts() {
@@ -620,24 +635,31 @@ protected Long readCountAllActiveProductsInternal(Date currentDate) {
620635
}
621636

622637
protected CriteriaQuery<Product> getCriteriaForActiveProducts(Date currentDate) {
638+
return getCriteriaForActiveProducts(currentDate, null);
639+
}
640+
641+
protected CriteriaQuery<Product> getCriteriaForActiveProducts(Date currentDate, Long lastId) {
623642
// Set up the criteria query that specifies we want to return Products
624643
CriteriaBuilder builder = em.getCriteriaBuilder();
625644
CriteriaQuery<Product> criteria = builder.createQuery(Product.class);
626-
645+
627646
// The root of our search is Product
628647
Root<ProductImpl> product = criteria.from(ProductImpl.class);
629-
648+
630649
// We need to filter on active date on the sku
631650
Join<Product, Sku> sku = product.join("defaultSku");
632651
product.fetch("defaultSku");
633-
652+
634653
// Product objects are what we want back
635654
criteria.select(product);
636-
655+
637656
// Ensure the product is currently active
638657
List<Predicate> restrictions = new ArrayList<Predicate>();
639658
attachActiveRestriction(currentDate, product, sku, restrictions);
640-
659+
if (lastId != null) {
660+
restrictions.add(builder.gt(product.get("id").as(Long.class), lastId));
661+
}
662+
641663
// Add the restrictions to the criteria query
642664
criteria.where(restrictions.toArray(new Predicate[restrictions.size()]));
643665

0 commit comments

Comments
 (0)