Permalink
Browse files

Eliminate duplicate row count checks

  • Loading branch information...
lmcalpin committed Nov 23, 2011
1 parent e7361be commit 0a1652f73f64408b870b5f009f172de3fdc68a1b
View
@@ -12,3 +12,4 @@ build.bat
test-result
doc
logs
+tmp
View
@@ -1,125 +0,0 @@
-= Play--Paginate
-
-The Paginate module adds two new tags:
-
- #{paginate.list items:var, as:'ref'/}, which works as a drop-in replacement for #{list/} to show one page at a time
-
-and
-
- #{paginate.controls items:var /} to display the pagination controls
-
-Also, add
-
- <link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/play-pagination.css'}">
-
-if you want to use the default stylesheet.
-
-== Using Paginator from your Controllers
-
-The paginator can be used several ways:
-
-1) You can wrap a raw List. Your controller can simply create a List:
-
- List<Foo> values = ...;
- render(values);
-
-The view will simply refer to that List:
-
- #{paginate.list items:values, as:'row'/}
-
-Behind the scenes, the control will autobox the raw List into a ValuePaginator helper class.
-
-2) You can manually wrap the List with our ValuePaginator helper class.
-
- List<Foo> values = ...;
- ValuePaginator entites = new ValuePaginator(values);
- render(entities);
-
-3) You can wrap the keys. Using our ModelPaginator helper class, we will lazily lookup only the rows for the current page that is being rendered.
-
- List<Long> keys = ... "SELECT id FROM Foo" ... ;
- ModelPaginator entities = new ModelPaginator(Foo.class, keys);
- render(entities);
-
-4) You can supply a Play! Model and optionally a filter and let the ModelPaginator helper class figure out the rest.
-
- ModelPaginator entities = new ModelPaginator(Foo.class, "foo=?", "bar");
- render(entities);
-
-You can also do sorting as well.
-
- ModelPaginator entities = new ModelPaginator(Foo.class, "foo=?", "bar").orderBy("ID DESC"));
- render(entities);
-
-== Using Paginator from your Views
-
-You will display a page from a collection by including the following tags:
-
- #{paginate.list items:values, as:'r'}
- ${r} <!-- displays the value for each row -->
- #{/paginate.list}
-
-The tag will insert special variables into the template that you can reference if you want to determine which row number is being displayed,
-and the parity of the row. The variables append "_index", "_parity", "_isFirst", and "_isLast" to the field name specified in the "as"
-parameter.
-
-For example, in the tag above, the row variable is called "r", and the following variables will be available.
-
- ${r_index} displays the row number (starting from 1)
- ${r_isFirst} is true for row #1 and false elsewhere
- ${r_isLast} is true for the last row in the Collection
- ${r_parity} returns "even" for even-numbered rows and "odd" for odd-numbered rows
-
-You can also use the standard Play! #{else} tag. The contents within this tag will be rendered if the collection is empty:
-
- #{paginate.list items:emptyCollection, as:'doesntmatter'}
- This content won't be displayed
- #{/paginate.list}
- #{else}
- Empty list!
- #{/else}
-
-== Customization
-
-Pagination controls are controlled by the view paginate/Controls.html and can be overridden in your project.
-
-The following properties are available to customize pagination display:
-
-- get/setBoundaryControlsEnabled: determines whether the First and Last buttons are displayed
-- get/setPagesDisplayed: customizes the number of pages that show up between the forward/backward controls
-- get/setPageSize: determines the number of rows we display per page
-
-By default, paginator uses the "page" request parameter to determine what page you are viewing. If you would
-like to override that, you can add a "paginator.parameter.name" entry to your application.conf:
-
- paginator.parameter.name=__pagenumber
-
-However, using the default page request parameter will paginate every single pagination control on the page.
-To avoid that, you need to invoke the setParameterName() method in your controller.
-
- ModelPaginator entities = new ModelPaginator(...);
- entities.setParameterName("foo");
- render(entities);
-
-The example above will use the request parameter "foo" to capture the current page number for the ModelPaginator
-associated with the variable named "entities."
-
-There is currently no way to change the parameter name used for Lists that are autoboxed into ValuePaginators.
-
-== Row Count Summary
-
-An additional summary tag is available if you would like to display the message: "Displaying rows X to Y
-out of Z records."
-
- #{paginate.summary items:paginator /}
-
-== Version History
-
-0.1 - 7/26/2011
- - initial versioned release
-0.11 - 9/13/2011
- - minor bug fixes
-??? - (usually the head Play! module will have the latest changes)
- - add support for Sets and Maps
- - add multidb support
- - support entities with non-default naming (@Entity(name="..."))
View
@@ -0,0 +1,122 @@
+h1. paginate
+
+paginate (http://github.com/lmcalpin/Play--Paginate) is a replacement for the standard #{list/} Play! tag.
+
+h2. Getting Started
+
+To include paginate in an existing project add the following lines to your **conf/application.conf** file
+
+bc.
+module.paginate=${play.path}/modules/paginate-head
+
+h2. Using paginate
+
+You can use paginate by creating an instance of a Paginator object. Two are provided for you, though you can always create your own:
+
+**play.modules.paginate.ModelPaginator** is used to paginate standard Play! JPA-based models.
+
+bc. public static void index() {
+ ModelPaginator paginator = new ModelPaginator(TheModel.class);
+ render(paginator);
+ }
+
+You can also provide a JPA-QL WHERE clause and/or an ORDER clause to sort and filter the results.
+
+bc. ModelPaginator entities = new ModelPaginator(Foo.class, "foo=?", "bar").orderBy("ID DESC"));
+ render(entities);
+
+**play.modules.paginate.ValuePaginator ** is used to wrap any existing List.
+
+bc. public static void index() {
+ List<T> realList = ...;
+ ValuePaginator paginator = new ValuePaginator(realList);
+ render(paginator);
+ }
+
+You can also simply provide a standard Java Collections API List, and behind the scenes, it will be autoboxed into a ValuePaginator.
+
+bc. public static void index() {
+ List<T> realList = ...;
+ render(realList);
+ }
+
+From your view, include the pagination list and controls:
+
+bc. #{paginate.list items:paginator, as:'r'}
+ ... ${r} // or whatever
+ #{/paginate.list}
+ #{paginate.controls items:paginator /}
+
+If you would like to use the default stylesheet, include this somewhere in your layout:
+
+bc. <link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/play-pagination.css'}">
+
+If you would like to include a summary "Displaying rows X to Y", you may include the
+summary tag:
+
+bc. #{paginate.summary items:paginator/}
+
+You can use the standard Play! #{else} tag with #{paginate.list}.
+The contents within this tag will be rendered if the collection is empty:
+
+bc. #{paginate.list items:emptyCollection, as:'doesntmatter'}
+ This content won't be displayed
+ #{/paginate.list}
+ #{else}
+ Empty list!
+ #{/else}
+
+h2. Customization
+
+Pagination controls are controlled by the view paginate/Controls.html and can be overridden in your project.
+
+The following properties are available to customize pagination display:
+
+- get/setBoundaryControlsEnabled: determines whether the First and Last buttons are displayed
+- get/setPagesDisplayed: customizes the number of pages that show up between the forward/backward controls
+- get/setPageSize: determines the number of rows we display per page
+
+*Request Parameters*
+
+By default, paginator uses the "page" request parameter to determine what page you are viewing. If you would
+like to override that, you can add a "paginator.parameter.name" entry to your application.conf:
+
+ paginator.parameter.name=__pagenumber
+
+However, using the default page request parameter will paginate every single pagination control on the page.
+To avoid that, you need to invoke the setParameterName() method in your controller.
+
+ ModelPaginator entities = new ModelPaginator(...);
+ entities.setParameterName("foo");
+ render(entities);
+
+The example above will use the request parameter "foo" to capture the current page number for the ModelPaginator
+associated with the variable named "entities."
+
+There is currently no way to change the parameter name used for Lists that are autoboxed into ValuePaginators.
+
+*Query Cache*
+
+The JPA paginators try to use Hibernate's query cache, if you have one configured. You can disable this by
+adding "paginator.jpa.useQueryCache=false" to your application.conf.
+
+h2. Row Count Summary
+
+An additional summary tag is available if you would like to display the message: "Displaying rows X to Y
+out of Z records."
+
+ #{paginate.summary items:paginator /}
+
+h2. Version History
+
+0.1 - 7/26/2011
+ - initial versioned release
+0.11 - 9/13/2011
+ - minor bug fixes
+0.12 11/23/2011
+ - add support for Sets and Maps
+ - add multidb support
+ - support entities with non-default naming (@Entity(name="..."))
+ - use query cache if available
+ - bug fix: eliminate duplicate row count checks
+
@@ -68,25 +68,42 @@ bc. #{paginate.list items:emptyCollection, as:'doesntmatter'}
h2. Customization
-By default, a request parameter "page" is used to determine which page is being viewed in a paginated list. If you would rather use an alternate name, you can customize this in your **conf/application.conf** file.
+Pagination controls are controlled by the view paginate/Controls.html and can be overridden in your project.
-bc. paginator.parameter.name=__page
-
-In addition, the Paginator classes expose properties that you can use to determine how many items are displayed per page, as well as how the controls will be displayed.
+The following properties are available to customize pagination display:
- get/setBoundaryControlsEnabled: determines whether the First and Last buttons are displayed
- get/setPagesDisplayed: customizes the number of pages that show up between the forward/backward controls
- get/setPageSize: determines the number of rows we display per page
+
+*Request Parameters*
-However, using the default page request parameter will paginate every single pagination control on the page.
+By default, paginator uses the "page" request parameter to determine what page you are viewing. If you would
+like to override that, you can add a "paginator.parameter.name" entry to your application.conf:
-To avoid that, you need to invoke the setParameterName() method in your controller.
+ paginator.parameter.name=__pagenumber
-bc. ModelPaginator entities = new ModelPaginator(...);
- entities.setParameterName("foo");
- render(entities);
+However, using the default page request parameter will paginate every single pagination control on the page.
+To avoid that, you need to invoke the setParameterName() method in your controller.
+ ModelPaginator entities = new ModelPaginator(...);
+ entities.setParameterName("foo");
+ render(entities);
+
The example above will use the request parameter "foo" to capture the current page number for the ModelPaginator
associated with the variable named "entities."
There is currently no way to change the parameter name used for Lists that are autoboxed into ValuePaginators.
+
+*Query Cache*
+
+The JPA paginators try to use Hibernate's query cache, if you have one configured. You can disable this by
+adding "paginator.jpa.useQueryCache=false" to your application.conf.
+
+h2. Row Count Summary
+
+An additional summary tag is available if you would like to display the message: "Displaying rows X to Y
+out of Z records."
+
+ #{paginate.summary items:paginator /}
+
View
Binary file not shown.
@@ -58,6 +58,7 @@
private RecordLocatorStrategy<T> recordLocatorStrategy;
private int pageNumber;
+ private Integer rowCount;
private final String action;
private String paramName;
private final Map<String, Object> viewParams;
@@ -311,7 +312,10 @@ public T set(int index, T element) {
}
public int size() {
- return recordLocatorStrategy.count();
+ if (this.rowCount == null) {
+ this.rowCount = recordLocatorStrategy.count();
+ }
+ return this.rowCount;
}
public List<T> subList(int fromIndex, int toIndex) {
@@ -11,6 +11,7 @@
import org.apache.commons.lang.StringUtils;
+import play.Play;
import play.db.jpa.JPA;
import play.db.jpa.Model;
import play.exceptions.UnexpectedException;
@@ -20,9 +21,12 @@
private Object[] params;
private String orderBy;
private final Class<T> typeToken;
+ private boolean useQueryCache;
public JPARecordLocatorStrategy(Class<T> typeToken) {
this.typeToken = typeToken;
+ String useQueryCacheStr = Play.configuration.getProperty("paginator.jpa.useQueryCache", "true");
+ this.useQueryCache = Boolean.parseBoolean(useQueryCacheStr);
}
/**
@@ -47,7 +51,7 @@ public JPARecordLocatorStrategy(Class<T> typeToken, List<K> keys) {
* @param params
*/
public JPARecordLocatorStrategy(Class<T> typeToken, String filter, Object... params) {
- this.typeToken = typeToken;
+ this(typeToken);
this.filter = filter;
this.params = params;
}
@@ -136,6 +140,9 @@ protected Query query(String select, boolean applyOrderBy) {
}
}
Query query = em.createQuery(hql.toString());
+ if (useQueryCache) {
+ query.setHint("org.hibernate.cacheable", true);
+ }
if (params != null) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i + 1, params[i]);

0 comments on commit 0a1652f

Please sign in to comment.