play4jpa icon indicating copy to clipboard operation
play4jpa copied to clipboard

ExpressionList and Page - Replacements

Open jaybytez opened this issue 10 years ago • 1 comments

I read quickly through your blog articles, and love the wrapper you have put around JPA. If I want to do a quick replace of my Ebean code, it looks like I just have to replace ExpressionList with a Java List (correct?).

Do you have an example of how to best replace the ebean Page example?

Play has this as the JPA solution for a Page, just want to understand how the PageQueryIterator would simplify this:

/**
 * Return a page of computer
 *
 * @param page Page to display
 * @param pageSize Number of computers per page
 * @param sortBy Computer property used for sorting
 * @param order Sort order (either or asc or desc)
 * @param filter Filter applied on the name column
 */
public static Page page(int page, int pageSize, String sortBy, String order, String filter) {
    if(page < 1) page = 1;
    Long total = (Long)JPA.em()
        .createQuery("select count(c) from Computer c where lower(c.name) like ?")
        .setParameter(1, "%" + filter.toLowerCase() + "%")
        .getSingleResult();
    @SuppressWarnings("unchecked")
            List<Computer> data = JPA.em()
        .createQuery("from Computer c where lower(c.name) like ? order by c." + sortBy + " " + order)
        .setParameter(1, "%" + filter.toLowerCase() + "%")
        .setFirstResult((page - 1) * pageSize)
        .setMaxResults(pageSize)
        .getResultList();
    return new Page(data, total, page, pageSize);
}

/**
 * Used to represent a computers page.
 */
public static class Page {

    private final int pageSize;
    private final long totalRowCount;
    private final int pageIndex;
    private final List<Computer> list;

    public Page(List<Computer> data, long total, int page, int pageSize) {
        this.list = data;
        this.totalRowCount = total;
        this.pageIndex = page;
        this.pageSize = pageSize;
    }

    public long getTotalRowCount() {
        return totalRowCount;
    }

    public int getPageIndex() {
        return pageIndex;
    }

    public List<Computer> getList() {
        return list;
    }

    public boolean hasPrev() {
        return pageIndex > 1;
    }

    public boolean hasNext() {
        return (totalRowCount/pageSize) >= pageIndex;
    }

    public String getDisplayXtoYofZ() {
        int start = ((pageIndex - 1) * pageSize + 1);
        int end = start + Math.min(pageSize, list.size()) - 1;
        return start + " to " + end + " of " + totalRowCount;
    }

}

Thanks!

jaybytez avatar Jun 10 '14 04:06 jaybytez

Hey @jaybytez,

if I'm right you won't ever use ExpressionList - you normally just use the Finder.query() method and then chain method calls as required (they all return a Query).

Regarding your Page question: The PagedQueryIterator does not support all the things as in the example. It is merely an implementation of the Iterator interface and as such does not support going backwards or asking for a specific page. It is only paged by means of loading batches - it would probably be good to rename it as a BatchedQueryIterator and implement a "real" PagedQueryIterator supporting the above given functionality.

Hope I could help, Michael

rose-m avatar Jun 19 '14 08:06 rose-m