Revision db3d35f7
#6612 generic dao list method providing a flexible multi property filter:
- PropertyNameMatchMode class introduces
- AbstractPagerImpl.limitStartforRange() to replace hasResultsInRange()
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ICdmEntityDao.java | ||
---|---|---|
225 | 225 |
* @param type |
226 | 226 |
* Restrict the query to objects of a certain class, or null for |
227 | 227 |
* all objects of type T or subclasses |
228 |
* @param propertyName
|
|
229 |
* The name of a entity property.
|
|
230 |
* @param value
|
|
231 |
* The value for the comparison with the entity property.
|
|
232 |
* @param matchMode
|
|
233 |
* The comparison method to use. <b>NOTE:</b> For non string type properties you must use
|
|
228 |
* @param restrictions
|
|
229 |
* This defines a filter for multiple properties represented by the map keys. Sine the keys are of the type
|
|
230 |
* {@link PropertyNameMatchMode} for each property a single MatchMode is defined. Multiple alternative values
|
|
231 |
* can be supplied per property, that is the values per property are combined with OR. The per property
|
|
232 |
* restrictions are combined with AND. </br>
|
|
233 |
* <b>NOTE:</b> For non string type properties you must use |
|
234 | 234 |
* {@link MatchMode#EXACT}. If set <code>null</code> {@link MatchMode#EXACT} will be used |
235 | 235 |
* as default. |
236 | 236 |
* @param limit |
... | ... | |
246 | 246 |
* @return |
247 | 247 |
* @throws DataAccessException |
248 | 248 |
*/ |
249 |
public List<T> list(Class<? extends T> type, String propertyName, Object value, MatchMode matchMode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
|
|
249 |
public List<T> list(Class<? extends T> type, Map<PropertyNameMatchMode, Collection<? extends Object>> restrictions, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
|
|
250 | 250 |
|
251 | 251 |
/** |
252 | 252 |
* Counts the Cdm entities matching the restrictions defined by |
... | ... | |
255 | 255 |
* @param type |
256 | 256 |
* Restrict the query to objects of a certain class, or null for |
257 | 257 |
* all objects of type T or subclasses |
258 |
* @param propertyName
|
|
259 |
* The name of a entity property.
|
|
260 |
* @param value
|
|
261 |
* The value for the comparison with the entity property.
|
|
262 |
* @param matchMode
|
|
263 |
* The comparison method to use. <b>NOTE:</b> For non string type properties you must use
|
|
258 |
* @param restrictions
|
|
259 |
* This defines a filter for multiple properties represented by the map keys. Sine the keys are of the type
|
|
260 |
* {@link PropertyNameMatchMode} for each property a single MatchMode is defined. Multiple alternative values
|
|
261 |
* can be supplied per property, that is the values per property are combined with OR. The per property
|
|
262 |
* restrictions are combined with AND. </br>
|
|
263 |
* <b>NOTE:</b> For non string type properties you must use |
|
264 | 264 |
* {@link MatchMode#EXACT}. If set <code>null</code> {@link MatchMode#EXACT} will be used |
265 | 265 |
* as default. |
266 | 266 |
* @param criteria |
... | ... | |
268 | 268 |
* |
269 | 269 |
* @return |
270 | 270 |
*/ |
271 |
public int count(Class<? extends T> type, String propertyName, Object value, MatchMode matchMode);
|
|
271 |
public int count(Class<? extends T> type, Map<PropertyNameMatchMode, Collection<? extends Object>> restrictions);
|
|
272 | 272 |
|
273 | 273 |
/** |
274 | 274 |
* Returns a sublist of CdmBase instances of type <TYPE> stored in the database. |
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/PropertyNameMatchMode.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
6 |
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
|
7 |
* See LICENSE.TXT at the top of this package for the full license terms. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.persistence.dao.common; |
|
10 |
|
|
11 |
import eu.etaxonomy.cdm.persistence.query.MatchMode; |
|
12 |
|
|
13 |
/** |
|
14 |
* @author a.kohlbecker |
|
15 |
* @since May 8, 2017 |
|
16 |
* |
|
17 |
*/ |
|
18 |
public class PropertyNameMatchMode { |
|
19 |
|
|
20 |
private String propertyName; |
|
21 |
|
|
22 |
private MatchMode matchMode; |
|
23 |
|
|
24 |
|
|
25 |
|
|
26 |
/** |
|
27 |
* @param propertyName |
|
28 |
* @param matchMode |
|
29 |
*/ |
|
30 |
public PropertyNameMatchMode(String propertyName, MatchMode matchMode) { |
|
31 |
this.propertyName = propertyName; |
|
32 |
this.matchMode = matchMode; |
|
33 |
} |
|
34 |
|
|
35 |
/** |
|
36 |
* @return the propertyName |
|
37 |
*/ |
|
38 |
public String getPropertyName() { |
|
39 |
return propertyName; |
|
40 |
} |
|
41 |
|
|
42 |
/** |
|
43 |
* @param propertyName the propertyName to set |
|
44 |
*/ |
|
45 |
public void setPropertyName(String propertyName) { |
|
46 |
this.propertyName = propertyName; |
|
47 |
} |
|
48 |
|
|
49 |
/** |
|
50 |
* @return the matchMode |
|
51 |
*/ |
|
52 |
public MatchMode getMatchMode() { |
|
53 |
return matchMode; |
|
54 |
} |
|
55 |
|
|
56 |
/** |
|
57 |
* @param matchMode the matchMode to set |
|
58 |
*/ |
|
59 |
public void setMatchMode(MatchMode matchMode) { |
|
60 |
this.matchMode = matchMode; |
|
61 |
} |
|
62 |
|
|
63 |
|
|
64 |
} |
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/CdmEntityDaoBase.java | ||
---|---|---|
55 | 55 |
import eu.etaxonomy.cdm.model.common.User; |
56 | 56 |
import eu.etaxonomy.cdm.model.common.VersionableEntity; |
57 | 57 |
import eu.etaxonomy.cdm.persistence.dao.common.ICdmEntityDao; |
58 |
import eu.etaxonomy.cdm.persistence.dao.common.PropertyNameMatchMode; |
|
58 | 59 |
import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer; |
59 | 60 |
import eu.etaxonomy.cdm.persistence.dto.MergeResult; |
60 | 61 |
import eu.etaxonomy.cdm.persistence.hibernate.PostMergeEntityListener; |
... | ... | |
452 | 453 |
* {@inheritDoc} |
453 | 454 |
*/ |
454 | 455 |
@Override |
455 |
public List<T> list(Class<? extends T> type, String propertyName, Object value, MatchMode matchMode,
|
|
456 |
public List<T> list(Class<? extends T> type, Map<PropertyNameMatchMode, Collection<? extends Object>> restrictions,
|
|
456 | 457 |
Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) { |
457 | 458 |
|
458 | 459 |
Criteria criteria = criterionForType(type); |
459 | 460 |
|
460 |
if (propertyName != null) { |
|
461 |
addRestriction(propertyName, value, matchMode, criteria); |
|
462 |
} |
|
461 |
addRestrictions(restrictions, criteria); |
|
463 | 462 |
|
464 | 463 |
addLimitAndStart(limit, start, criteria); |
465 | 464 |
addOrder(criteria, orderHints); |
... | ... | |
471 | 470 |
} |
472 | 471 |
|
473 | 472 |
/** |
473 |
* @param restrictions |
|
474 |
* @param criteria |
|
475 |
*/ |
|
476 |
private void addRestrictions(Map<PropertyNameMatchMode, Collection<? extends Object>> restrictions, Criteria criteria) { |
|
477 |
List<Criterion> perProperty = new ArrayList<>(restrictions.size()); |
|
478 |
for(PropertyNameMatchMode propMatchMode : restrictions.keySet()){ |
|
479 |
Collection<? extends Object> values = restrictions.get(propMatchMode); |
|
480 |
if(values != null && !values.isEmpty()){ |
|
481 |
Criterion[] predicates = new Criterion[values.size()]; |
|
482 |
int i = 0; |
|
483 |
for(Object v : values){ |
|
484 |
predicates[i++] = createRestriction(propMatchMode.getPropertyName(), v, propMatchMode.getMatchMode()); |
|
485 |
} |
|
486 |
perProperty.add(Restrictions.or(predicates)); |
|
487 |
} |
|
488 |
} |
|
489 |
if(!perProperty.isEmpty()){ |
|
490 |
criteria.add(Restrictions.and(perProperty.toArray(new Criterion[perProperty.size()]))); |
|
491 |
} |
|
492 |
} |
|
493 |
|
|
494 |
/** |
|
474 | 495 |
* @param propertyName |
475 | 496 |
* @param value |
476 | 497 |
* @param matchMode |
477 | 498 |
* @param criteria |
499 |
* @return |
|
478 | 500 |
*/ |
479 |
private void addRestriction(String propertyName, Object value, MatchMode matchMode, Criteria criteria) {
|
|
501 |
private Criterion createRestriction(String propertyName, Object value, MatchMode matchMode) {
|
|
480 | 502 |
Criterion restriction; |
481 | 503 |
if(matchMode == null) { |
482 | 504 |
restriction = Restrictions.eq(propertyName, value); |
... | ... | |
496 | 518 |
restriction = Restrictions.ilike(propertyName, queryString, org.hibernate.criterion.MatchMode.ANYWHERE); |
497 | 519 |
} |
498 | 520 |
} |
499 |
criteria.add(restriction);
|
|
521 |
return restriction;
|
|
500 | 522 |
} |
501 | 523 |
|
502 | 524 |
/** |
503 | 525 |
* {@inheritDoc} |
504 | 526 |
*/ |
505 | 527 |
@Override |
506 |
public int count(Class<? extends T> type, String propertyName, Object value, MatchMode matchMode) {
|
|
528 |
public int count(Class<? extends T> type, Map<PropertyNameMatchMode, Collection<? extends Object>> restrictions) {
|
|
507 | 529 |
|
508 | 530 |
Criteria criteria = criterionForType(type); |
509 | 531 |
|
510 |
if (propertyName != null) { |
|
511 |
addRestriction(propertyName, value, matchMode, criteria); |
|
512 |
} |
|
532 |
addRestrictions(restrictions, criteria); |
|
513 | 533 |
|
514 | 534 |
criteria.setProjection(Projections.projectionList().add(Projections.rowCount())); |
515 | 535 |
|
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/agent/AgentDaoImplTest.java | ||
---|---|---|
15 | 15 |
|
16 | 16 |
import java.io.FileNotFoundException; |
17 | 17 |
import java.util.ArrayList; |
18 |
import java.util.Collection; |
|
19 |
import java.util.HashMap; |
|
18 | 20 |
import java.util.List; |
21 |
import java.util.Map; |
|
19 | 22 |
import java.util.UUID; |
20 | 23 |
|
21 |
import org.hibernate.criterion.Criterion; |
|
22 |
import org.hibernate.criterion.Restrictions; |
|
23 | 24 |
import org.junit.After; |
24 | 25 |
import org.junit.Assert; |
25 | 26 |
import org.junit.Before; |
... | ... | |
35 | 36 |
import eu.etaxonomy.cdm.model.view.AuditEvent; |
36 | 37 |
import eu.etaxonomy.cdm.model.view.context.AuditEventContextHolder; |
37 | 38 |
import eu.etaxonomy.cdm.persistence.dao.agent.IAgentDao; |
39 |
import eu.etaxonomy.cdm.persistence.dao.common.PropertyNameMatchMode; |
|
38 | 40 |
import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao; |
39 | 41 |
import eu.etaxonomy.cdm.persistence.query.MatchMode; |
40 | 42 |
import eu.etaxonomy.cdm.persistence.query.OrderHint; |
... | ... | |
260 | 262 |
@DataSet("AgentDaoImplTest.xml") |
261 | 263 |
public void testListPeopleFiltered() { |
262 | 264 |
|
263 |
List<AgentBase> result = agentDao.list(null, (String)null, null, (MatchMode)null, (Integer)null, (Integer)null, null, null); |
|
265 |
Map<PropertyNameMatchMode, Collection<? extends Object>> restrictions = new HashMap<>(); |
|
266 |
List<AgentBase> result = agentDao.list(null, restrictions, (Integer)null, (Integer)null, null, null); |
|
264 | 267 |
Assert.assertNotNull("list() should return a list",result); |
265 | 268 |
Assert.assertEquals("list() should return 9 AgentBase entities in the current view", 9 ,result.size()); |
266 | 269 |
|
267 |
List<AgentBase> personResults = agentDao.list(Person.class, (String)null, null, (MatchMode)null, (Integer)null, (Integer)null, null, null);
|
|
270 |
List<AgentBase> personResults = agentDao.list(Person.class, restrictions, (Integer)null, (Integer)null, null, null);
|
|
268 | 271 |
Assert.assertEquals("list() should return 5 Persons entities", 5, personResults.size()); |
269 | 272 |
|
270 |
personResults = agentDao.list(Person.class, "firstname", "Ben", MatchMode.EXACT, (Integer)null, (Integer)null, null, null); |
|
273 |
Collection<String> values = new ArrayList<>(); |
|
274 |
PropertyNameMatchMode firstNameExact = new PropertyNameMatchMode("firstname", MatchMode.EXACT); |
|
275 |
restrictions.put(firstNameExact, values); |
|
276 |
|
|
277 |
personResults = agentDao.list(Person.class, restrictions, (Integer)null, (Integer)null, null, null); |
|
278 |
Assert.assertEquals("list() empty value lists should be ignored", 5, personResults.size()); |
|
279 |
|
|
280 |
values.add("Ben"); |
|
281 |
restrictions.put(firstNameExact, values); |
|
282 |
personResults = agentDao.list(Person.class, restrictions, (Integer)null, (Integer)null, null, null); |
|
271 | 283 |
Assert.assertEquals("list() should return 1 AgentBase entity having the firstname 'Ben'", 1 ,personResults.size()); |
272 | 284 |
} |
273 | 285 |
|
274 | 286 |
@Test |
275 | 287 |
@DataSet("AgentDaoImplTest.xml") |
276 | 288 |
public void testCountPeopleFiltered() { |
277 |
List<Criterion> restrictions = new ArrayList<Criterion>(); |
|
278 | 289 |
|
279 |
Assert.assertEquals("count() should return 9 AgentBase entities", 9 , agentDao.count(null, (String)null, null, (MatchMode)null)); |
|
290 |
Map<PropertyNameMatchMode, Collection<? extends Object>> restrictions = new HashMap<>(); |
|
291 |
Assert.assertEquals("count() should return 9 AgentBase entities", 9 , agentDao.count(null, restrictions)); |
|
292 |
|
|
293 |
Assert.assertEquals("count() should return 5 Persons entities", 5, agentDao.count(Person.class, restrictions)); |
|
280 | 294 |
|
281 |
Assert.assertEquals("count() should return 5 Persons entities", 5, agentDao.count(Person.class, (String)null, null, (MatchMode)null)); |
|
295 |
Collection<String> values = new ArrayList<>(); |
|
296 |
PropertyNameMatchMode firstNameExact = new PropertyNameMatchMode("firstname", MatchMode.EXACT); |
|
297 |
restrictions.put(firstNameExact, values); |
|
298 |
Assert.assertEquals("count() empty value lists should be ignored", 5, agentDao.count(Person.class, restrictions)); |
|
282 | 299 |
|
283 |
restrictions.add(Restrictions.eq("firstname", "Ben")); |
|
284 |
Assert.assertEquals("count() should return 1 Persons entity having the firstname 'Ben'", 1 , agentDao.count(Person.class, "firstname", "Ben", MatchMode.EXACT)); |
|
300 |
values.add("Ben"); |
|
301 |
restrictions.put(firstNameExact, values); |
|
302 |
Assert.assertEquals("count() should return 1 Persons entity having the firstname 'Ben'", 1 , agentDao.count(Person.class, restrictions)); |
|
285 | 303 |
} |
286 | 304 |
|
287 | 305 |
@Test |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IRegistrationService.java | ||
---|---|---|
78 | 78 |
* @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based, |
79 | 79 |
* can be null, equivalent of starting at the beginning of the recordset) |
80 | 80 |
* @param submitter |
81 |
* The user who submitted the Registration
|
|
81 |
* Limits the result set to Registrations having the given submitter. This filter is ignored if set to <code>null</code>.
|
|
82 | 82 |
* @param includedStatus |
83 | 83 |
* filters the Registration by the RegistrationStatus. Only Registration having one of |
84 | 84 |
* the supplied status will included. |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/RegistrationServiceImpl.java | ||
---|---|---|
9 | 9 |
package eu.etaxonomy.cdm.api.service; |
10 | 10 |
|
11 | 11 |
import java.util.ArrayList; |
12 |
import java.util.Arrays; |
|
12 | 13 |
import java.util.Collection; |
14 |
import java.util.HashMap; |
|
13 | 15 |
import java.util.List; |
16 |
import java.util.Map; |
|
14 | 17 |
import java.util.Optional; |
15 | 18 |
|
16 | 19 |
import org.springframework.beans.factory.annotation.Autowired; |
... | ... | |
18 | 21 |
import org.springframework.transaction.annotation.Transactional; |
19 | 22 |
|
20 | 23 |
import eu.etaxonomy.cdm.api.service.pager.Pager; |
21 |
import eu.etaxonomy.cdm.api.service.pager.PagerUtils; |
|
22 | 24 |
import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl; |
23 | 25 |
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl; |
24 | 26 |
import eu.etaxonomy.cdm.model.common.User; |
25 | 27 |
import eu.etaxonomy.cdm.model.name.Registration; |
26 | 28 |
import eu.etaxonomy.cdm.model.name.RegistrationStatus; |
27 | 29 |
import eu.etaxonomy.cdm.model.reference.Reference; |
30 |
import eu.etaxonomy.cdm.persistence.dao.common.PropertyNameMatchMode; |
|
28 | 31 |
import eu.etaxonomy.cdm.persistence.dao.name.IRegistrationDao; |
32 |
import eu.etaxonomy.cdm.persistence.query.MatchMode; |
|
29 | 33 |
import eu.etaxonomy.cdm.persistence.query.OrderHint; |
30 | 34 |
|
31 | 35 |
/** |
... | ... | |
56 | 60 |
long numberOfResults = dao.count(reference, includedStatus); |
57 | 61 |
|
58 | 62 |
List<Registration> results = new ArrayList<>(); |
59 |
if(AbstractPagerImpl.hasResultsInRange(numberOfResults, pageIndex, pageSize)) { |
|
60 |
Integer limit = PagerUtils.limitFor(pageSize); |
|
61 |
Integer start = PagerUtils.startFor(pageSize, pageIndex); |
|
62 |
results = dao.list(reference, includedStatus, limit, start, propertyPaths); |
|
63 |
int [] limitStart = AbstractPagerImpl.limitStartforRange(numberOfResults, pageIndex, pageSize); |
|
64 |
if(limitStart != null) { |
|
65 |
results = dao.list(reference, includedStatus, limitStart[0], limitStart[1], propertyPaths); |
|
63 | 66 |
} |
64 | 67 |
|
65 |
return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
|
|
68 |
return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results); |
|
66 | 69 |
} |
67 | 70 |
|
68 | 71 |
/** |
69 | 72 |
* {@inheritDoc} |
70 |
* TODO: includedStatus not yet implemented |
|
71 | 73 |
*/ |
72 | 74 |
@Override |
73 | 75 |
public Pager<Registration> page(User submitter, Collection<RegistrationStatus> includedStatus, |
74 | 76 |
Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths) { |
75 | 77 |
|
76 |
long numberOfResults = dao.count(Registration.class, "submitter", submitter, null); |
|
78 |
Map<PropertyNameMatchMode, Collection<? extends Object>> restrictions = new HashMap<>(); |
|
79 |
if(submitter != null){ |
|
80 |
restrictions.put(new PropertyNameMatchMode("submitter", MatchMode.EXACT), Arrays.asList(submitter)); |
|
81 |
} |
|
82 |
if(includedStatus != null && !includedStatus.isEmpty()){ |
|
83 |
restrictions.put(new PropertyNameMatchMode("status", MatchMode.EXACT), includedStatus); |
|
84 |
} |
|
85 |
|
|
86 |
long numberOfResults = dao.count(Registration.class, restrictions); |
|
77 | 87 |
|
78 | 88 |
List<Registration> results = new ArrayList<Registration>(); |
79 |
if(AbstractPagerImpl.hasResultsInRange(numberOfResults, pageIndex, pageSize)) { |
|
80 |
Integer limit = PagerUtils.limitFor(pageSize); |
|
81 |
Integer start = PagerUtils.startFor(pageSize, pageIndex); |
|
82 |
results = dao.list(Registration.class, "submitter", submitter, null, limit, start, orderHints, propertyPaths); |
|
89 |
int [] limitStart = AbstractPagerImpl.limitStartforRange(numberOfResults, pageIndex, pageSize); |
|
90 |
if(limitStart != null) { |
|
91 |
results = dao.list(Registration.class, restrictions, limitStart[0], limitStart[1], orderHints, propertyPaths); |
|
83 | 92 |
} |
84 | 93 |
|
85 |
return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
|
|
94 |
return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results); |
|
86 | 95 |
} |
87 | 96 |
|
88 | 97 |
|
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/pager/impl/AbstractPagerImpl.java | ||
---|---|---|
266 | 266 |
|
267 | 267 |
/** |
268 | 268 |
* Test if the the <code>numberOfResults</code> in the range of the page specified by <code>pageIndex</code> and <code>pageSize</code>. |
269 |
* |
|
269 |
* <p>
|
|
270 | 270 |
* When using this method in a service layer class you will also need to provide the according <code>limit</code> and <code>start</code> |
271 | 271 |
* parameters for dao list methods. The PagerUtil class provides the according methods for the required calculation: |
272 |
* {@link PagerUtils#limitFor(Integer)} and {@link PagerUtils#startFor(Integer, Integer)} |
|
272 |
* {@link PagerUtils#limitFor(Integer)} and {@link PagerUtils#startFor(Integer, Integer)}.<br/> |
|
273 |
* <b>NOTE:</b> It is highly recommended to use the {@link #limitStartforRange(Long, Integer, Integer)} method instead which already |
|
274 |
* includes the calculation of <code>limit</code> and <code>start</code>. |
|
273 | 275 |
* |
274 | 276 |
* @param numberOfResults |
275 | 277 |
* @param pageIndex |
276 | 278 |
* @param pageSize |
277 | 279 |
* @return |
280 |
* |
|
281 |
* @deprecated use {@link #limitStartforRange(Long, Integer, Integer)} instead if appropriate. |
|
278 | 282 |
*/ |
283 |
@Deprecated |
|
279 | 284 |
public static boolean hasResultsInRange(Long numberOfResults, Integer pageIndex, Integer pageSize) { |
280 | 285 |
return numberOfResults > 0 // no results at all |
281 | 286 |
&& (pageSize == null // page size may be null : return all in this case |
282 | 287 |
|| pageIndex != null && numberOfResults > (pageIndex * pageSize)); |
283 | 288 |
} |
284 | 289 |
|
290 |
/** |
|
291 |
* Test if the the <code>numberOfResults</code> in the range of the page specified by <code>pageIndex</code> and <code>pageSize</code>. |
|
292 |
* And returns the according <code>limit</code> and <code>start</code> values as an array in case the test is successful. If there is no |
|
293 |
* result in the specified range the return value will be <code>null</code>. |
|
294 |
* <p> |
|
295 |
* When using this method in a service layer class you will also need to provide the according <code>limit</code> and <code>start</code> |
|
296 |
* parameters for dao list methods. The PagerUtil class provides the according methods for the required calculation: |
|
297 |
* {@link PagerUtils#limitFor(Integer)} and {@link PagerUtils#startFor(Integer, Integer)} |
|
298 |
* |
|
299 |
* @param numberOfResults |
|
300 |
* @param pageIndex |
|
301 |
* @param pageSize |
|
302 |
* @return An <code>int</code> array containing limit and start: <code>new int[]{limit, start}</code> or null if there is no result in the range of |
|
303 |
* <code>pageIndex</code> and <code>pageSize</code>. |
|
304 |
*/ |
|
305 |
public static int[] limitStartforRange(Long numberOfResults, Integer pageIndex, Integer pageSize) { |
|
306 |
if(hasResultsInRange(numberOfResults, pageIndex, pageSize)){ |
|
307 |
return new int[]{PagerUtils.limitFor(pageSize), PagerUtils.startFor(pageSize, pageIndex)}; |
|
308 |
} |
|
309 |
return null; |
|
310 |
} |
|
311 |
|
|
285 | 312 |
} |
Also available in: Unified diff