1
1
/*
2
2
Copyright 2009-2014 Igor Polevoy
3
3
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
7
8
- http://www.apache.org/licenses/LICENSE-2.0
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
9
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
15
*/
16
16
17
17
@@ -45,41 +45,52 @@ public class Paginator<T extends Model> implements Serializable {
45
45
private int currentPage ;
46
46
private final boolean fullQuery ;
47
47
private final String countQuery ;
48
+ private boolean suppressCounts = false ;
49
+ private Long count = 0L ;
48
50
49
51
52
+ /**
53
+ * Convenience constructor. Calls {@link #Paginator(Class, int, String, Object...)} and passes true for <code>suppressCounts</code>.
54
+ */
55
+ public Paginator (Class <? extends T > modelClass , int pageSize , String query , Object ... params ) {
56
+ this (modelClass , pageSize , false , query , params );
57
+ }
58
+
50
59
/**
51
60
* Paginator is created with parameters to jump to chunks of result sets (pages). This class is useful "paging"
52
61
* through result on a user interface (web page).
53
- *
62
+ * <p/>
54
63
* <h4>Examples of a sub-query:</h4>
55
64
* <ul>
56
- * <li><code>"last_name like '%John%'"</code> - this is a sub-query, and the rest of the information will be filled out
65
+ * <li><code>"last_name like '%John%'"</code> - this is a sub-query, and the rest of the information will be filled out
57
66
* by this class</li>
58
- * <li> "*" - will search for all records, no filtering</li>
67
+ * <li> "*" - will search for all records, no filtering</li>
59
68
* </ul>
60
69
* Sub-query is used in simple cases, when filtering is done against one table.
61
- *
70
+ * <p/>
62
71
* <h4>Full query example</h4>
63
72
* <ul>
64
- * <li>"select * from people where last_name like '%John%'"</li>
73
+ * <li>"select * from people where last_name like '%John%'"</li>
65
74
* </ul>
66
75
* Full query is used in cases when select covers many tables. In this case, the selected columns need to include
67
76
* attributes of the model class.
68
77
*
69
- * @param modelClass model class mapped to a table.
70
- * @param pageSize number of items per page.
71
- * @param params a set of parameters if a query is parametrized (has question marks '?').
72
- * @param query this is a query that will be applied every time a new page is requested; this
73
- * query should not contain limit, offset or order by clauses of any kind, Paginator will do this automatically.
74
- * This parameter can have two forms, a sub-query or a full query.
75
- *
76
- *
78
+ * @param modelClass model class mapped to a table.
79
+ * @param pageSize number of items per page.
80
+ * @param suppressCounts suppress calling "select count(*)... " on a table each time. If set to true,
81
+ * it will call count only once. If set to false, it will call count each time
82
+ * {@link #getCount()} is called from {@link #hasNext()} as well.
83
+ * @param params a set of parameters if a query is parametrized (has question marks '?').
84
+ * @param query this is a query that will be applied every time a new page is requested; this
85
+ * query should not contain limit, offset or order by clauses of any kind, Paginator will do this automatically.
86
+ * This parameter can have two forms, a sub-query or a full query.
77
87
*/
78
- public Paginator (Class <? extends T > modelClass , int pageSize , String query , Object ... params ) {
88
+ public Paginator (Class <? extends T > modelClass , int pageSize , boolean suppressCounts , String query , Object ... params ) {
79
89
80
- try {
90
+ this .suppressCounts = suppressCounts ;
91
+ try {
81
92
Class .forName (modelClass .getName ());
82
- }catch (ClassNotFoundException e ){
93
+ } catch (ClassNotFoundException e ) {
83
94
throw new InitException (e );
84
95
}
85
96
@@ -99,7 +110,7 @@ public Paginator(Class<? extends T> modelClass, int pageSize, String query, Obje
99
110
} else if (query .equals ("*" )) {
100
111
if (params .length == 0 ) {
101
112
this .countQuery = metaModel .getDialect ().selectCount (tableName );
102
- } else {
113
+ } else {
103
114
throw new IllegalArgumentException ("cannot provide parameters with query: '*'" );
104
115
}
105
116
} else {
@@ -122,7 +133,7 @@ public Paginator orderBy(String orderBys) {
122
133
* This method will return a list of records for a specific page.
123
134
*
124
135
* @param pageNumber page number to return. This is indexed at 1, not 0. Any value below 1 is illegal and will
125
- * be rejected.
136
+ * be rejected.
126
137
* @return list of records that match a query make up a "page".
127
138
*/
128
139
public LazyList <T > getPage (int pageNumber ) {
@@ -146,35 +157,36 @@ public LazyList<T> getPage(int pageNumber) {
146
157
*
147
158
* @return index of current page, or 0 if this instance has not produced a page yet.
148
159
*/
149
- public int getCurrentPage (){
160
+ public int getCurrentPage () {
150
161
return currentPage ;
151
162
}
152
163
153
164
/**
154
165
* Synonym for {@link #hasPrevious()}.
155
166
*
156
- * @return true if a previous page is available.
167
+ * @return true if a previous page is available.
157
168
*/
158
- public boolean getPrevious (){
169
+ public boolean getPrevious () {
159
170
return hasPrevious ();
160
171
}
161
- public boolean hasPrevious (){
172
+
173
+ public boolean hasPrevious () {
162
174
return currentPage > 1 && currentPage <= pageCount ();
163
175
}
164
176
165
177
/**
166
178
* Synonym for {@link #hasNext()}.
167
- *
168
- * @return true if a next page is available.
179
+ *
180
+ * @return true if a next page is available.
169
181
*/
170
- public boolean getNext (){
182
+ public boolean getNext () {
171
183
return hasNext ();
172
184
}
173
185
174
- public boolean hasNext (){
186
+ public boolean hasNext () {
175
187
return currentPage < pageCount ();
176
188
}
177
-
189
+
178
190
public long pageCount () {
179
191
try {
180
192
long results = getCount ();
@@ -189,12 +201,12 @@ private LazyList<T> find(String query, Object... params) {
189
201
if (query .equals ("*" )) {
190
202
if (params .length == 0 ) {
191
203
return findAll ();
192
- } else {
204
+ } else {
193
205
throw new IllegalArgumentException ("cannot provide parameters with query: '*'" );
194
206
}
195
207
}
196
- return fullQuery ? new LazyList <T >(true , metaModel , this .query , params )
197
- : new LazyList <T >(query , metaModel , params );
208
+ return fullQuery ? new LazyList <T >(true , metaModel , this .query , params )
209
+ : new LazyList <T >(query , metaModel , params );
198
210
}
199
211
200
212
private LazyList <T > findAll () {
@@ -207,20 +219,24 @@ private LazyList<T> findAll() {
207
219
* @return total count of records based on provided criteria
208
220
*/
209
221
public Long getCount () {
210
- Long result = null ;
211
- if (metaModel .cached ()) {
212
- result = (Long ) QueryCache .instance ().getItem (metaModel .getTableName (), countQuery , params );
213
- if (result == null ) {
214
- result = doCount ();
215
- QueryCache .instance ().addItem (metaModel .getTableName (), countQuery , params , result );
222
+ if (count == 0L || !suppressCounts ) {
223
+ if (metaModel .cached ()) {
224
+ count = (Long ) QueryCache .instance ().getItem (metaModel .getTableName (), countQuery , params );
225
+ if (count == null || count == 0 ) {
226
+ count = doCount ();
227
+ QueryCache .instance ().addItem (metaModel .getTableName (), countQuery , params , count );
228
+ }
229
+ } else {
230
+ count = doCount ();
216
231
}
232
+ return count ;
233
+
217
234
} else {
218
- result = doCount () ;
235
+ return count ;
219
236
}
220
- return result ;
221
237
}
222
238
223
- private Long doCount (){
239
+ private Long doCount () {
224
240
return Convert .toLong (new DB (metaModel .getDbName ()).firstCell (countQuery , params ));
225
241
}
226
242
}
0 commit comments