Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 #mH@ /6,#[
U}v`~'K
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 B6XO&I1c
tMr7d
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 k(Yz2
xh6(~'$
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 |9@,ri\'Rg
Z:b?^u4.
。 EZtU6kW"
Xj?Wvt
分页支持类: QxT'\7f
~% hdy@
java代码: *miG<
#ydold{F
~G@NWF?7
package com.javaeye.common.util; $+gQnI3w
Ht`fC|E
import java.util.List; /iW+<@Mas
$Dg-;I
publicclass PaginationSupport { l![M,8
NW|B|kc
publicfinalstaticint PAGESIZE = 30; e8a^"Z`a
6(|mdk`i
privateint pageSize = PAGESIZE; J,a&"eOZ
1-RY5R}VR
privateList items; mq:k|w^6
IrwQ~z3I
privateint totalCount; y@LI miRG
^[ae
)}
privateint[] indexes = newint[0]; {9IRW\kn
W5jwD
privateint startIndex = 0; >OG189O
.j6udiv5
public PaginationSupport(List items, int AR"2?2<mJ7
wG3L+[,
totalCount){ w,~*ead
setPageSize(PAGESIZE); 7j&
t{q5
setTotalCount(totalCount); .5JIQWE(
setItems(items); = XZU9df
setStartIndex(0); /"m s
} 5hs_k[q
]l7W5$26 @
public PaginationSupport(List items, int Po>6I0y
SA,~q&
totalCount, int startIndex){ t@KTiJI
]
setPageSize(PAGESIZE); +Z#=z,.^
setTotalCount(totalCount); FlO?E3d
setItems(items); O[X*F2LC4
setStartIndex(startIndex); g 2Fg
} :J;U~emq
8)B{x[?|
public PaginationSupport(List items, int Za.}bR6?Y
)! [B(
totalCount, int pageSize, int startIndex){ #83
setPageSize(pageSize); ]+lT*6P*
setTotalCount(totalCount); (6%T~|a
setItems(items); 3j#VKj+Uc
setStartIndex(startIndex); a %go[_w
} XY0kd&N8
3
98)\3o
publicList getItems(){ ;W0J
return items; 0 '&C5v'
} g%2G=gR$?z
ra^</o/
publicvoid setItems(List items){ 2BY|Cp4R
this.items = items; b"g^Jm! j
} MmJMx
3Vu}D(PJ
publicint getPageSize(){ UMcM&yu-
return pageSize; 3 s\UU2yr
} ]0i[=
Vjs2Yenx
publicvoid setPageSize(int pageSize){ %<i sdvF
this.pageSize = pageSize; ,>|tQ'
} 2%/F`_XbP
F6{g{
B
publicint getTotalCount(){ ,#a4P`q'iC
return totalCount; R P{pEd
} Owp]>e
v]JET9hY
publicvoid setTotalCount(int totalCount){ ~B<\#oO
if(totalCount > 0){ Rsx6vF8]5
this.totalCount = totalCount;
&_)P)L
int count = totalCount / UG vIH m
R ENCk(
pageSize; =B&|\2`{)
if(totalCount % pageSize > 0) (o>N*?,}
count++; ~|u;z,\
indexes = newint[count]; %6ckau1_;
for(int i = 0; i < count; i++){ Y XhZWo{B
indexes = pageSize * 'O%*:'5k
o*T?f)_[p
i; .M6. ]H
} GTs,?t16/
}else{ I!zoo[/)%
this.totalCount = 0; x1=`Z@^
} U<6)CW1;
} -6MPls+
-=-^rQx9
publicint[] getIndexes(){ sBlq)h;G?6
return indexes; lh-.I]>&`
} %
:G78.
Ehy(;n)\
publicvoid setIndexes(int[] indexes){ jLFaf#G]
this.indexes = indexes; ;&lXgC^*
} (~|)Gmq2
`!8\|/
publicint getStartIndex(){ |\bNFnn(
return startIndex; c coi
} 5a |[cR
4lo7yx
publicvoid setStartIndex(int startIndex){ 51:5rN(_
if(totalCount <= 0) cg )(L;
this.startIndex = 0; #m#IBRD :
elseif(startIndex >= totalCount) &UDbH* !4=
this.startIndex = indexes ;apLMMsWC
g.\b@0Uy'
[indexes.length - 1]; CXUF=IE
elseif(startIndex < 0) R/u0,
this.startIndex = 0; >$kFYb>~q
else{ erI&XI
this.startIndex = indexes W{Qb*{9
{UH45#Ua
[startIndex / pageSize]; THl:>s
} Tp ;W
} :M6|V_Yp
:F d1k
Jm
publicint getNextIndex(){ TT/=0^"
int nextIndex = getStartIndex() + 5REH`-
7Kym|Zg
pageSize; 7$7|~k
if(nextIndex >= totalCount) !19T=p/:$
return getStartIndex(); U["<f`z4\
else 3 EAr=E]
return nextIndex; JP!e'oWxi
} 9#H0|zL
CCpRQKb=
publicint getPreviousIndex(){ 7]@M
int previousIndex = getStartIndex() - czw:xG!&
(,"%fc7<i
pageSize; mAH7;u<
if(previousIndex < 0) Gb2|e.z
return0; hz bvR~rn
else '3XOU.
return previousIndex; Qc33CA
} yO-2.2h
r
E1ouz!D
} '"Cqq{*
W}F~vx.
wz+mFf
:WH{wm|
抽象业务类 E.yFCaL
java代码: 6oKlr,.
2 U%t
D~qi6@Ga
/** #WA7}tHb
* Created on 2005-7-12 Eoz/]b
*/ EQnU:a
package com.javaeye.common.business; Ym%#"
6n:X
p_yO
import java.io.Serializable; ~m R^j
import java.util.List; w2$ L;q
2C0j.Ib
import org.hibernate.Criteria; 2SC'Z>A
import org.hibernate.HibernateException; 0#c-qy
import org.hibernate.Session; 1`II%mf[
import org.hibernate.criterion.DetachedCriteria; i Q3wi
import org.hibernate.criterion.Projections; AU*]D@H
import daY0;,>
MPp:EH
org.springframework.orm.hibernate3.HibernateCallback; L9[m/(:y
import ^`-Hg= d
qHrIs-NR
org.springframework.orm.hibernate3.support.HibernateDaoS 5m;pHgkb
$sL+k 'dY
upport; 3b?-83a
>$<Q:o}^
import com.javaeye.common.util.PaginationSupport; <-d-.
8
NgGpLdaC2v
public abstract class AbstractManager extends r& RJ'z
vr>J$(F
HibernateDaoSupport { WOYZ
i(u zb<
privateboolean cacheQueries = false; a"+/fC`
CE183l\
privateString queryCacheRegion; bz&9]%S<
,0L< wa
publicvoid setCacheQueries(boolean 11$v~<M
R^E-9S\@
cacheQueries){ WUDXx %
this.cacheQueries = cacheQueries; uxrNkZia
} 4pDZ +}p
Kd#64NSi$A
publicvoid setQueryCacheRegion(String TR?jT
U
B_r:da CS:
queryCacheRegion){ v&^N +>p
this.queryCacheRegion = RplcM%YJn
kSJ:4! lFU
queryCacheRegion; X7aj/:fXe
} hO3C _}
]~WIGl"g
publicvoid save(finalObject entity){ 8BIPEY -I?
getHibernateTemplate().save(entity); Xp^>SSt:4
} F7p`zf@O]
X bV?=
publicvoid persist(finalObject entity){ j{5oXW
getHibernateTemplate().save(entity); XF4NRs
} 0Oq5;5
m[5ed1+
publicvoid update(finalObject entity){ OUHd@up@n
getHibernateTemplate().update(entity); Qe<c@i"
} Tq6@
1j6p
QD[l 6
publicvoid delete(finalObject entity){ IetV ]Ff6
getHibernateTemplate().delete(entity); Z${@;lgP
} ~fA H6FdZ\
zpcm`z
publicObject load(finalClass entity, =66,$~g{
]o8~b-
finalSerializable id){ V[|k:($
return getHibernateTemplate().load RML'C:1
lce~6}
(entity, id); !hPe*pPVV)
} el0W0T
(7aE!r\Ab
publicObject get(finalClass entity, Lj3q?>D*^6
[h
:FJ
finalSerializable id){ b~G|Bhxa
return getHibernateTemplate().get
BgG+
HQ|{!P\/?U
(entity, id); TLzcQ |
} m+'X8}GC#O
XG6UV('
publicList findAll(finalClass entity){ PDh1*bf{u
return getHibernateTemplate().find("from Z Q9's
)&elr,b/y
" + entity.getName()); f1VA61z{)
} 20uR? /|@
=7("xz%
publicList findByNamedQuery(finalString @}N;C..Y$
[C~{g#
namedQuery){ T\HP5&
return getHibernateTemplate _nnl+S>K
y+[wlo&WC
().findByNamedQuery(namedQuery); Yc'7F7.<6
} [26([H
YI?y_S
publicList findByNamedQuery(finalString query, 2|^bDg;W+u
].w$b)G
finalObject parameter){ }oTac
return getHibernateTemplate e.g$|C^$m
(3G]-
().findByNamedQuery(query, parameter); P(r}<SM
} 80M4~'3
KK*"s^L
publicList findByNamedQuery(finalString query, ?+#E&F
?3i-wpzMp
finalObject[] parameters){ M*c`@\
return getHibernateTemplate sXSZ#@u,WN
pKSVT
().findByNamedQuery(query, parameters); ZjJEjw
} T+/Gz'
=M9Od7\J
publicList find(finalString query){ 'W j Q
return getHibernateTemplate().find .es= w=
}FRyG%
(query); f&>Q6 {*]
} B6Tn8@O
L7*~8Y
publicList find(finalString query, finalObject BT+ws@|[
'x10\Q65[
parameter){ hpym!G
return getHibernateTemplate().find MhB kr{8
p.1|bXY`
(query, parameter); f;%4O'
} m[u
6<C
1<qq6 9x
public PaginationSupport findPageByCriteria ^Q_0Zq^H
*%cI,}%
(final DetachedCriteria detachedCriteria){ jKu"Vi|j>
return findPageByCriteria A|@d4+
2S8/
lsB
(detachedCriteria, PaginationSupport.PAGESIZE, 0); ;z7iUke0%
} 'bg%9}
nyPA`)5F0
public PaginationSupport findPageByCriteria GRj{*zs
B: uW(E
(final DetachedCriteria detachedCriteria, finalint 'gE_xn7j
G";yqG
startIndex){ _B|g)Rdv
return findPageByCriteria #,qikKjt2
HWGlC <
(detachedCriteria, PaginationSupport.PAGESIZE, M|`%4vk>
.|{*.YE
startIndex); *pvhkJ g(
} }qXi;u))
FUm-Fp
public PaginationSupport findPageByCriteria )f'cy@b
.x1EdfHed/
(final DetachedCriteria detachedCriteria, finalint >UuLSF}
(85F1"Jp
pageSize, <OW` )0UX
finalint startIndex){ n4CzReG
return(PaginationSupport) 7z6y n=B
/gHRJ$2|Sx
getHibernateTemplate().execute(new HibernateCallback(){ TZZqV8
publicObject doInHibernate w>rglm&
<
v_ ?}
(Session session)throws HibernateException { 3!CI=(^IY
Criteria criteria = GI7CZ
A HKS
[ N
detachedCriteria.getExecutableCriteria(session); M>_S%V4a
int totalCount = t/S~CIA
mnXaf)"
((Integer) criteria.setProjection(Projections.rowCount /)y~%0
/{1 xpR
()).uniqueResult()).intValue(); '&T4ryq3"
criteria.setProjection lTdYPqMi
r"rID
RQ"
(null); oc-7gz)
List items = hgKs[ySo,3
"mT~_BsD
criteria.setFirstResult(startIndex).setMaxResults "Rs^0iT7>
K=Fcy#,f
(pageSize).list(); })bTQj7
PaginationSupport ps = 0 x"3
fwxyZBr
new PaginationSupport(items, totalCount, pageSize, M6|Q~8$
c6dL
S
startIndex); /tP"r}l
return ps; !OWV* v2
} o~^hsm[44J
}, true); S`X;2\:
} A"z')
[N#2uo
public List findAllByCriteria(final Cg21-G.
UXa3>q>
DetachedCriteria detachedCriteria){ (g~&$&pa
return(List) getHibernateTemplate FJ>| l#nO
-_pI:K[
().execute(new HibernateCallback(){ m2<sVTN`^
publicObject doInHibernate )X| uOg&|
w>VM--
(Session session)throws HibernateException { -oe&1RrdVg
Criteria criteria = }N4=~'R
oOe5IczS(
detachedCriteria.getExecutableCriteria(session); {My/+{eS!?
return criteria.list(); r"U$udwjg
}
b9w9M&?fT
}, true); D
7H$!(F>
} UO<%|{W+
RpS'Tz}
public int getCountByCriteria(final ,1F3";`n[
O&\;BF5:R
DetachedCriteria detachedCriteria){ W/{HZ< :.
Integer count = (Integer) +l&ZN\@0X
WZ"x\K-;
getHibernateTemplate().execute(new HibernateCallback(){ [al$7R&
publicObject doInHibernate 4(
^Ht
,n~H]66n
(Session session)throws HibernateException { yHk/8
Criteria criteria = )0RH"#,2L
x8gUP
detachedCriteria.getExecutableCriteria(session); ,uEWnZ"4
return ] X4A)%i
oe4Fy}Y_;
criteria.setProjection(Projections.rowCount t~ Q{\!
,p>=WX
()).uniqueResult(); 0rA&_K[#-<
} s'fHhG6
}, true);
}r*t
V)
return count.intValue(); R^fVwDl\
} ) <^9`
} (+bk +0
U{n
0Z
SH5GW3\h
f#/v^Ql*
+vBq,'k`
m/%sBw\rx
用户在web层构造查询条件detachedCriteria,和可选的 . v0 .wG
RP z0WP
startIndex,调用业务bean的相应findByCriteria方法,返回一个 SgFyv<6>:
Bk>Ch#`Bw
PaginationSupport的实例ps。 N ~g'Z
`
% nP13V]
ps.getItems()得到已分页好的结果集 KS1Z&~4
ps.getIndexes()得到分页索引的数组 Qy5\qW'
ps.getTotalCount()得到总结果数 lJu2}XRiU
ps.getStartIndex()当前分页索引 nXk<DlTws
ps.getNextIndex()下一页索引 SpjL\ p0
ps.getPreviousIndex()上一页索引 Iz!Blk
B {f&'1pp/
xhj
A!\DS
>Ex\j?
u0#q)L8
2|kx:^D p
qA#!3<
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 kOx2P(UAEx
ZVVK:dDgt
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 ]f-< s,@
G;qC&7T
一下代码重构了。 W !2(Ph*
9] Uvy|
我把原本我的做法也提供出来供大家讨论吧: Bj;Fy9[yb
AnfJyltS
首先,为了实现分页查询,我封装了一个Page类: W(1p0|WQ:
java代码: Fla,#uB
%#yCp2
O:q 0-
/*Created on 2005-4-14*/ IdUMoLL?
package org.flyware.util.page;
o-_0
>QU1_'1r
/** 5L"{J5R}
* @author Joa |u<qbl
* 2W~,,$
G
*/ /
\!hW-+]W
publicclass Page { ;Pnz4Y4|eU
\NDSpT<Z
/** imply if the page has previous page */ k6QQoLb$V
privateboolean hasPrePage; T`Sp!
BPIp3i
/** imply if the page has next page */ smF#'"{
privateboolean hasNextPage; 8AOJ'~$
8sx\b
/** the number of every page */ P'KaW u9z
privateint everyPage; KaZ*HPe(
O+@"l$;N
/** the total page number */ {Fta4D_1N
privateint totalPage; d/+sR@\
T""X~+{Z@
/** the number of current page */ #|
`W ]
privateint currentPage; q<>LK
6K5KZZG
/** the begin index of the records by the current 1%G<gbHpI
/KO!s,Nk
query */ s{2BG9s
privateint beginIndex; L L7a20
l&dHH_m3
iKu[j)F
/** The default constructor */ 7,d^?.~S
public Page(){ $C##S@
]m{;yOQdsC
} r3mB"("Z'
tV9BVsN
/** construct the page by everyPage $Ud-aRlD
* @param everyPage @ZK#Y){
* */ EtWpB g
public Page(int everyPage){ fJtJ2x i
this.everyPage = everyPage; }"06'
} ZsirX~W<
j/5>zS
/** The whole constructor */ )Mx[;IwE
public Page(boolean hasPrePage, boolean hasNextPage, 5][Rvu0
xC9^x7%3O
72GXgah
int everyPage, int totalPage, x#|=.T
int currentPage, int beginIndex){ f\!*%xS;
this.hasPrePage = hasPrePage; p{"p<XFyO
this.hasNextPage = hasNextPage; CeNpJ
this.everyPage = everyPage;
.taJCE
this.totalPage = totalPage; #r `hK)
this.currentPage = currentPage; R4"["T+L`
this.beginIndex = beginIndex; (d |
} $h0]
OY*BVJ^
/** L,!Z
* @return 9t(B{S
* Returns the beginIndex. ]F r+cP
*/ |{k;pfPV
publicint getBeginIndex(){ !u.{<51b
return beginIndex; zO<EbqNe!
} 2T<QG>;)j
URck#5
/** ps[TiW{q;
* @param beginIndex g2l|NI#c^
* The beginIndex to set. c@1C|
*/ 8c\mm 0n
publicvoid setBeginIndex(int beginIndex){ YES!?^}
this.beginIndex = beginIndex; `<zaxO
} K 2$mz
@I2m4Q{O
/** 46o3F"
* @return [-f0s;F1%
* Returns the currentPage. MeW8aLr
*/ m=k(6
publicint getCurrentPage(){ !s/ij'T
return currentPage; .r)WDR
} f(=yC}si
W78Z<Vm
/** u|<Z};a
* @param currentPage Ih!UL:Ckh
* The currentPage to set. [&k[k)
*/ `9B xDp]I
publicvoid setCurrentPage(int currentPage){ M.1R]x(|
this.currentPage = currentPage; -N(y+~wN
} :!;BOCTYI
$74ZC
M
/** +?zyFb]Km
* @return F'lG=c3N
* Returns the everyPage. HdGAE1eU]}
*/ ,GS8Gu
publicint getEveryPage(){ BhJqMK>'S
return everyPage; d i`}Y&
} =L{lt9qQz
_SjS^z~
/** a"&@G=M@d
* @param everyPage "tBdz V
* The everyPage to set. 2GLq#")P
*/ 9-eYCg7C|
publicvoid setEveryPage(int everyPage){ W}EI gVHs
this.everyPage = everyPage; r.**
z j
} UTc$zc7
ca*USM
/** 64z9Yr@
* @return L.$9ernVY
* Returns the hasNextPage.
M.zS +
*/ ;'!U/N;-
publicboolean getHasNextPage(){ 2x{@19w)C
return hasNextPage; =H.l/'/Z
} z11;r]VI
S,fMGKcq
/** 2/sD#vC
* @param hasNextPage w&f8AY)#]4
* The hasNextPage to set. kEf}yTy
*/ c!T^JZBb
publicvoid setHasNextPage(boolean hasNextPage){ HWT0oh]
this.hasNextPage = hasNextPage; ^*"&e\+p
} M7/P&d
cEnkt=
/** P5* :r3>
* @return 6_=qpP-?
* Returns the hasPrePage. JQYIvo1,Q
*/ ,*Y*ov23aQ
publicboolean getHasPrePage(){ 7)O?jc
return hasPrePage; vnMt>]w-}
} oD4NQR
k:4 Zc3
/** >};,Byv!%
* @param hasPrePage ~`
@dI
* The hasPrePage to set. e'[T5HI
*/ *#;8mM
publicvoid setHasPrePage(boolean hasPrePage){ )|@b
GEk
this.hasPrePage = hasPrePage; iN8?~T}w
} g4<%t,(88E
'C+z
/** Qh%/{6(u
* @return Returns the totalPage. U8]L3&~
* n{d}]V@
*/ QG?7L_I
publicint getTotalPage(){ sqi~j(&\1
return totalPage; vD D !.i
} }X$vriW
*_`T*$
/** v:B_%-GfOA
* @param totalPage $SSE\+|3
* The totalPage to set. lyI
rO"o
*/ @^a6^*X>
publicvoid setTotalPage(int totalPage){ gn1`ZYg
this.totalPage = totalPage; N~{0QewMI'
} ;@Ep?S@
z{pNQ[t1Z
} zT#36+_?
V9-pY/v9
E:V&:9aQ@
!H{)L@f
Msn)jh
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 <*0MD6$5
gGw6c" FRQ
个PageUtil,负责对Page对象进行构造: H$KE*Wwq
java代码: 8A"[n>931
DBAJkBs
VH4P|w[YF
/*Created on 2005-4-14*/ %}%D8-d}G
package org.flyware.util.page; T?!^-PD9*
ehtiu!Vk
import org.apache.commons.logging.Log; (M4~N)7<P5
import org.apache.commons.logging.LogFactory; >C+0LF`U
3:<+9X
/** WGN[`D"
* @author Joa pu=T
pSZ
* %56pP"w
*/ Odxq ]HlbO
publicclass PageUtil { %\_I%
yF
B, xrZ s
privatestaticfinal Log logger = LogFactory.getLog L$zT`1Hy
W=5+k0Q
(PageUtil.class); JmrQDO_(
&UP@Sr0D7
/** '[-gKn
* Use the origin page to create a new page AJ2Xq*fk
* @param page B
h@R9O<
* @param totalRecords |}^[f]
* @return 6R%c+ok8i
*/ YH)Unql
publicstatic Page createPage(Page page, int =}\]i*
jPPaL]
totalRecords){ |(}uagfrd
return createPage(page.getEveryPage(), *0{MAm
po*s
page.getCurrentPage(), totalRecords); -Hh$3Uv
} UYW%%5p?
v!t*Ng
/** |o~FKy1'z\
* the basic page utils not including exception Vyj>&"28
$^I uE0.
handler H|0B*i@81
* @param everyPage <E$P
* @param currentPage +6*oO|
* @param totalRecords lk \|EG
* @return page 6ecr]=Cv
*/ KZ ?<&x
publicstatic Page createPage(int everyPage, int 6Kh:m-E9
1KruGq~
currentPage, int totalRecords){ ?XsL4HIx
everyPage = getEveryPage(everyPage); Z{chAg\
currentPage = getCurrentPage(currentPage); 0vS%m/Zi-
int beginIndex = getBeginIndex(everyPage, \4K8*`$
b6bmvHD
currentPage); Mki(,Y|1~
int totalPage = getTotalPage(everyPage, vMzR3@4e
L45&O
*%
totalRecords); YM3oqS D
boolean hasNextPage = hasNextPage(currentPage, }n6BI}n
dmP*2
totalPage); u):z1b3*?
boolean hasPrePage = hasPrePage(currentPage); pTGq4v@6x
qw%4j9}
returnnew Page(hasPrePage, hasNextPage, NxNR;wz>l
everyPage, totalPage, @MtF^y
currentPage, uWx/V+w
<^R\N#
beginIndex); ;Bcf~[ErM
} (z2)<_bXJ
rMe`HM@
privatestaticint getEveryPage(int everyPage){ (S5'iksx
return everyPage == 0 ? 10 : everyPage; }w8h^(+B
} }O2hhh_
O~{Zs\u9
privatestaticint getCurrentPage(int currentPage){ 4E4o=Z|K
return currentPage == 0 ? 1 : currentPage; >m}.}g8
} 7*'_&0
UbC)XiO
privatestaticint getBeginIndex(int everyPage, int 85"DS-+e
;TmwIZ
currentPage){ A!fjw
return(currentPage - 1) * everyPage; hx)Ed
} KPW: r#d
|t]-a%A=w
privatestaticint getTotalPage(int everyPage, int 3(^9K2.s}
lxbbyy25
totalRecords){ QV{Nq=%]
int totalPage = 0; i`2Q;Az_P6
.
Nog.
if(totalRecords % everyPage == 0) 4I:Jb;k>
totalPage = totalRecords / everyPage; (`3Bi]7
else @=Ly#HuUM
totalPage = totalRecords / everyPage + 1 ; *sAoYx
xhUQ.(S`r6
return totalPage; 8Y5*
1E*
} rRT9)wDa
b\=0[kBQw
privatestaticboolean hasPrePage(int currentPage){ ;a{ Dr
return currentPage == 1 ? false : true; C9gF2ii|?
} deHBY4@
ywq{9)vq
privatestaticboolean hasNextPage(int currentPage, Esw&ScBOP