Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 J|4q9$
HQPb
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 4C AV)
GjTj..G/
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 }#0MJ6L
/tIR}qK
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 OS|uZ<"Rq3
kkWqP20q
。 F>N3GPRl
HqM>K*XKU
分页支持类: "p]F q,
2K >tI9);
java代码: zx)^!dEMM
/P_1vQq
lIR0jgP@z
package com.javaeye.common.util; -anLp8G*
3Ee8_(E\
import java.util.List; 6@0
wKV!D
O<}^`4d
publicclass PaginationSupport { gkxEy5c[
{8L)Fw
publicfinalstaticint PAGESIZE = 30; $lJu2omi1
5<0d2bK$
privateint pageSize = PAGESIZE; $^&SEz
dU!`aPL?
privateList items; iC U[X&
r 5$(
privateint totalCount; n])-+[F
>)Ih[0~M
privateint[] indexes = newint[0]; _ F0qqj
G5^gwG+
privateint startIndex = 0; bYzBe\^3q3
WA);Z=
public PaginationSupport(List items, int Salu[)+?
%9_wDfw~
totalCount){ OtopA)
setPageSize(PAGESIZE); " mKMym2
setTotalCount(totalCount); Y`FGD25`
setItems(items); nMU#g])y)
setStartIndex(0); f;/t7=>d
} C,C=W]G
Z_%}pe39B
public PaginationSupport(List items, int Y^)VHE]
v}6YbY Tq
totalCount, int startIndex){ &`7~vA&c
setPageSize(PAGESIZE); &`rV{%N"
setTotalCount(totalCount); 2|k*rv}l
setItems(items); l3aG#4jj
setStartIndex(startIndex); +n(H"I7cU
} ~L(_q]
(l22p
public PaginationSupport(List items, int nf< <]iHf
";~}"Yz?[
totalCount, int pageSize, int startIndex){ d9/E^)TT
setPageSize(pageSize); !2x"'o
setTotalCount(totalCount); \Rn.ug
setItems(items); ErC~,5dj;n
setStartIndex(startIndex); 3&*0n^g
} [BhpfZNKRA
RCt)qh+
publicList getItems(){ T4
SByX9
return items; ej,MmLu~^
} (2@b ,w^
m@JU).NKCS
publicvoid setItems(List items){ >Z^7=5K"O
this.items = items; 4\(;}M-R{
} e:[Kp6J
?HIc=
publicint getPageSize(){ \Y9=dE}
return pageSize; X_
>B7(k
} kSNVI-Wzu
oW]&]*>J
publicvoid setPageSize(int pageSize){ 17D167\X
this.pageSize = pageSize; z!Kadqns
} |iM*}Ix-
v )7d
publicint getTotalCount(){ 3:Co K#
return totalCount; J=K3S9:n]g
} cb%w,yXw
O8u"Y0$*w
publicvoid setTotalCount(int totalCount){ l^`!:BOtR
if(totalCount > 0){ >mF`XbS
this.totalCount = totalCount; RAE|eTnna
int count = totalCount / rvE!Q=y~
d+T]EpQJ*
pageSize; ;JL@V}L,
if(totalCount % pageSize > 0) }Tc)M_
count++; !.t'3~dUf$
indexes = newint[count]; 56<LMY|d
for(int i = 0; i < count; i++){ p'w[5'
indexes = pageSize * h]EXD
_ux6SIyp`
i; X<9DE!/)
} .j&jf^a5
}else{ [/#n+sz.A
this.totalCount = 0; "\_}"0H
} -nk %He
} r kD4}jV
>a4Bfnf"eI
publicint[] getIndexes(){ Ne9
.wd
return indexes; |x5w;=
} JR<R8+@g_
;%k%AXw
publicvoid setIndexes(int[] indexes){ Z#J{tXZc
this.indexes = indexes; gSe{S
} _SFD}w3b$
9MYt4
publicint getStartIndex(){ lmc-ofEv
return startIndex; gRqz8UI
} W@S9}+wl*
ah<f&2f
publicvoid setStartIndex(int startIndex){ x4( fW\
if(totalCount <= 0) eD(a
+El}
this.startIndex = 0; /6.b>|zF
elseif(startIndex >= totalCount) -"nYCF
this.startIndex = indexes ./g#<
``z="oD
[indexes.length - 1]; AdYQhF##
elseif(startIndex < 0) *oWzH_
this.startIndex = 0; bG&qgbN>
else{ K*}j1A
this.startIndex = indexes pxC5a i
UCWU|r<s,
[startIndex / pageSize]; ky%%H;
} A&7jE:Ew
} lKwcT!Q4
]a%Kn]HI&2
publicint getNextIndex(){ t8+93,*B
int nextIndex = getStartIndex() + atAA[~
l85"C
pageSize; Yt'o#"R)
if(nextIndex >= totalCount) >dGYZfqD
return getStartIndex(); H}~^,B2;
else 6};oLnO
return nextIndex; 1GdgF?4
} KAzRFX),
}>:X|4]
publicint getPreviousIndex(){ :F\f}G3
int previousIndex = getStartIndex() - <coCu0
B;Z^.3
pageSize; q Q'@yTVN
if(previousIndex < 0) *S4P'JSY
return0; @$R a
else 9 JtG&^*
return previousIndex; "lZ<bG
} 8IH gsW";
T1&H!
} )]R?v,9*D
9R[','x
ZM?r1Z4
A{%;Hd`0/
抽象业务类 nE;gM1I
java代码: mg(56)
eV0S:mit
h6N}sLM{0
/** oUSG`g^P(M
* Created on 2005-7-12 Sq,ty{j2%
*/ Ke'2"VkQt
package com.javaeye.common.business; }C1wfZ~F~
X%CPz.G
import java.io.Serializable; du,-]fF
import java.util.List; |Ze}bM=N
.*blM1+6i/
import org.hibernate.Criteria; gj^]}6-P
import org.hibernate.HibernateException; Q8oo5vqQ#C
import org.hibernate.Session; JrTBe73.]j
import org.hibernate.criterion.DetachedCriteria; M3 u8NRd5|
import org.hibernate.criterion.Projections; NGUGN~p
import /nFw
J|24I4
org.springframework.orm.hibernate3.HibernateCallback; qEr[fC@x
import yZ$;O0f&&
TWEqv<c
org.springframework.orm.hibernate3.support.HibernateDaoS );DIrA
@|Bp'`j%J
upport; nF$)F?||
vPNZFi-(
import com.javaeye.common.util.PaginationSupport; b'5pQ2Mq
_PXo'*j
public abstract class AbstractManager extends jgw'MpQm{
0\nhg5]?
HibernateDaoSupport { _Pi:TxY
[F[<2{FQF
privateboolean cacheQueries = false; Jjh!/pWZ4
6G$tYfX
privateString queryCacheRegion; Q8cPKDB
VDjIs UUX
publicvoid setCacheQueries(boolean =w$"wzc
]u ~Fn2
cacheQueries){ 6_K#,_oZ
this.cacheQueries = cacheQueries; bk9~63tN+>
} 59BHGvaF
SJ7=<y}[d
publicvoid setQueryCacheRegion(String aq/Y}s?
N/{Yi
_n
queryCacheRegion){ g]
C3lf-
this.queryCacheRegion = qq3Qd,$Z
V^/^OR4k
queryCacheRegion; 8yz((?LrDh
} :fKz^@mY4
-JhjTA
publicvoid save(finalObject entity){ eEGcio}_I9
getHibernateTemplate().save(entity); IBNQmVRrI
} _JIUds5
=,8Eo"~\
publicvoid persist(finalObject entity){ (Cd{#j<
getHibernateTemplate().save(entity); }d\Tk(W
} *[~o~e/YCb
6 %k+0\d
publicvoid update(finalObject entity){ SLjf<.S
getHibernateTemplate().update(entity); RHl=$Hm.%
} _ u|FJTk
X<}o>
6|d
publicvoid delete(finalObject entity){ po2[uJ
getHibernateTemplate().delete(entity); hd
;S>K/C
} Y0fO.k#C^
D<3V#Opw
publicObject load(finalClass entity, eQaxZMU
dGD^op,6g
finalSerializable id){ MAD}Tv\S7
return getHibernateTemplate().load +=~%S)9F
-0VA!3l
(entity, id); Q$h:[_v
} 11y.z^
t-7U1B}=<C
publicObject get(finalClass entity, Z'*Z@u3
Sa1z,EP
finalSerializable id){ zIm_7\e
return getHibernateTemplate().get Tq\~<rEo
c6Aut`dK
(entity, id); z(`
}:t
} ^2C /!Y<
4o4 =
publicList findAll(finalClass entity){ T<f\*1~^
return getHibernateTemplate().find("from +fd@K
A6NxM8ybn+
" + entity.getName()); VwOG?5W/
} Q1nDl
"rx^M*"
publicList findByNamedQuery(finalString y3cf[Q
QOV}5 0
namedQuery){ R{)
Q1~H=q
return getHibernateTemplate )jlP
cO-
_}e7L7B7g
().findByNamedQuery(namedQuery); J}(6>iuQY?
} q1f=&kGX~
)W`SC mr]
publicList findByNamedQuery(finalString query, )>y
k-
v0Ai!#
finalObject parameter){ &@%
b?~
return getHibernateTemplate [Y$5zeA
<8rgtu!VU
().findByNamedQuery(query, parameter); h@~:(:zU$
} Z6Nj<2u2
U!c]_q
publicList findByNamedQuery(finalString query, I( ]BMMj
8M^wuRn
finalObject[] parameters){ Z&FkLww
return getHibernateTemplate K4! P'
Gz>Lqd
().findByNamedQuery(query, parameters); %M{k.FE(
} g ?afX1Sg
2yN%~C?$
publicList find(finalString query){ @iU%`=ziz
return getHibernateTemplate().find FXx.$W
_i3i HR?
(query); Ag0]U
} 6hkkNXqkf
i`prv&
publicList find(finalString query, finalObject 1GtOA3,~;-
"~u_\STn <
parameter){ T8n-u b<
return getHibernateTemplate().find U~aWG\h#X
Aoj6k\YX
(query, parameter); 31~hlp;
} Zta$R,[9h
NQ?x8h3
public PaginationSupport findPageByCriteria 4d!S#zx
;}LJh8_
(final DetachedCriteria detachedCriteria){ hwiKOP
return findPageByCriteria ~}BJ0P(VMc
W1vCN31
(detachedCriteria, PaginationSupport.PAGESIZE, 0); #wr2imG6
} QwBXlO?
p ZtgIS(3
public PaginationSupport findPageByCriteria Q6=MS>JW]w
sltk@
(final DetachedCriteria detachedCriteria, finalint 7Yuk
Rho5s@N 7
startIndex){ HOfF"QAR$
return findPageByCriteria yz?q(]
c4\C[$
(detachedCriteria, PaginationSupport.PAGESIZE, 8Jr1_a
l]H0g[
startIndex); >9=:sSQu
} G]4OFz+
vv &BhIf3
public PaginationSupport findPageByCriteria n12UBvc}%
7F9;Su3.
(final DetachedCriteria detachedCriteria, finalint nTs/Q V
j eq:
pageSize, ~b Rd)1
finalint startIndex){ g5y;?fqJ
return(PaginationSupport) $Z ]z
]=x\b^
getHibernateTemplate().execute(new HibernateCallback(){ g`n;R
publicObject doInHibernate J*j5#V];
qgx?"$ Z
(Session session)throws HibernateException { >Q=Ukn;k
Criteria criteria = W5.Va.
cD2+hp|9
detachedCriteria.getExecutableCriteria(session); Iq^if>
int totalCount = 78d_io}w
JB^Q\;$
((Integer) criteria.setProjection(Projections.rowCount vZu~LW@1
"~/9F
()).uniqueResult()).intValue(); h%TLD[[/jr
criteria.setProjection >&WhQhZ3kg
ZY cd.? :6
(null); 3?.1nGu
List items = (#|{%4g@>
M4KWN'
criteria.setFirstResult(startIndex).setMaxResults SdJ/4&{ !
*V1J4 u
(pageSize).list(); pzhl*ss"6
PaginationSupport ps = nWJ:=JQ i"
+@<KC
new PaginationSupport(items, totalCount, pageSize, ghAi{@s$)
inAAgW#s}
startIndex); [h&BAR/ 2
return ps; +th%enRB
} k1='c7s
}, true); A&,,9G<
} <7XT\?%F
T6M+|"92
public List findAllByCriteria(final XIAeCU
zl%>`k!>
DetachedCriteria detachedCriteria){ 8K{[2O7i)
return(List) getHibernateTemplate .lN s4e
;%!B[+ut"
().execute(new HibernateCallback(){ nfdq y)
publicObject doInHibernate ?LaUed'
wRtZ`o
(Session session)throws HibernateException { ,v9f~qh
Criteria criteria = LL*mgTQ
@=Fi7M
detachedCriteria.getExecutableCriteria(session); 8VQ 24r
return criteria.list(); ?okx<'"[
} )ev<7g9*q
}, true); g(ogXA1
} k2 Q
qZxm!
(% _n!ip^
public int getCountByCriteria(final +iO/m
>\Sr{p5KR
DetachedCriteria detachedCriteria){ +q<B.XxkA
Integer count = (Integer) )|bC^{kH!l
Ts$@s^S]
getHibernateTemplate().execute(new HibernateCallback(){ [I;^^#'P
publicObject doInHibernate %~xGkk"I
#Q"O4 b:8
(Session session)throws HibernateException { PVOx`<ng
Criteria criteria = ANi)q$:{
MV>$BW
detachedCriteria.getExecutableCriteria(session); 1O/
g&u
return K(}AX+rIg
lfZ04M{2
criteria.setProjection(Projections.rowCount 5ETip'<KT6
O1&b]C#
()).uniqueResult(); >Z.\J2wM<j
} ^' M>r(t
}, true); }J:+{4Yn
return count.intValue(); Z3TS,a1I4
} 8;14Q7,S
} k^"bLf(4
W,^W^:m-x
Gq<X4C#|
yifY%!@Xu
KJ2Pb"s
7CXW#H
用户在web层构造查询条件detachedCriteria,和可选的 <_Z:'~Zp
2dp>Z",
startIndex,调用业务bean的相应findByCriteria方法,返回一个 =Z=o#46JY
BVsD(
@lX
PaginationSupport的实例ps。 0+Ta%H{
tVrY3)c
ps.getItems()得到已分页好的结果集 F!zP<A"
ps.getIndexes()得到分页索引的数组 ,GWNLm\5
ps.getTotalCount()得到总结果数 mE`kjmX{ E
ps.getStartIndex()当前分页索引 <f@"HG
l
ps.getNextIndex()下一页索引 40E#JF#
ps.getPreviousIndex()上一页索引 &k-Vcrcz
3pf[M{dG
2{-ZD ,(u7
Twn4lG4~
FR2=
las"z
BH]Yn u&o
3rLTF\
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 !Z
VU,b>
~{sG| ;/!*
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 lj+u@Z<xA
w 4[{2
一下代码重构了。 4DZ-bt'
;7N{^"r
我把原本我的做法也提供出来供大家讨论吧: D}8EER b
iq(
)8nxi
首先,为了实现分页查询,我封装了一个Page类: >pUtwIP
java代码: jw-0M1B
7{&|;U
%HrAzM.QBF
/*Created on 2005-4-14*/ N F)~W#
package org.flyware.util.page; w$JvB5O
2UGsYQn
/** II6CHjW`;
* @author Joa MEB it
* vWAL^?HUP
*/ "DYJ21Ut4
publicclass Page { f^W;A"+
&b:1I7Cp*
/** imply if the page has previous page */ t!RiU ZAo
privateboolean hasPrePage; >2~=)L
k:7(D_
/** imply if the page has next page */ (o`{uj{!
privateboolean hasNextPage; 2}8v(%s p
oq}'}`lw"
/** the number of every page */ s{1sE)_
privateint everyPage; .V,@k7U,V
=>-Rnc@
/** the total page number */ #\=F O>
privateint totalPage; B
{>7-0
s0vDHkf8
/** the number of current page */ .mR8q+I6
privateint currentPage; A}l3cP;
`#
q.;u?,|E/
/** the begin index of the records by the current CB^U6ZS
Hm*/C4B`
query */ ?`?)QE8
privateint beginIndex; *WuID2cOI
T:~vk.Or
E 7{U|\
/** The default constructor */ ~A\GT$
public Page(){ :.Wr{"`
yK=cZw%D
} z:wutqru
x<ZJb
/** construct the page by everyPage " )1V]}+m
* @param everyPage lgk.CC
* */ *_d7E
public Page(int everyPage){ ;>Ib^ov
this.everyPage = everyPage;
XwJ7|cB
} oG_~q
w|h
8)_XJ"9)G
/** The whole constructor */ _z|65H
public Page(boolean hasPrePage, boolean hasNextPage, ds<2I,t
nWw":K<@Q_
Hquc
o
int everyPage, int totalPage, X4~y7
int currentPage, int beginIndex){ #cI{Fe0h
this.hasPrePage = hasPrePage; ]>5/PD,wWy
this.hasNextPage = hasNextPage; o6.^*%kM'
this.everyPage = everyPage; 3[Qxd{8r
this.totalPage = totalPage; yPb" V
this.currentPage = currentPage; GjvOM y
this.beginIndex = beginIndex; I&x=;
} R{SF(g3
+~ P2C6@G
/** n{argI8wF
* @return Q+{xZ'o"Z
* Returns the beginIndex. EM(gmWHij
*/ ;U+3w~
publicint getBeginIndex(){ L>Fa^jq5
return beginIndex; _-K2/6zy
} ,/Z%@-rF
3YOq2pW72G
/** C)ERUH2i
* @param beginIndex :!WHFB
o 8
* The beginIndex to set. ^ @s1Z7
*/ Y!w`YYKP
publicvoid setBeginIndex(int beginIndex){ vc;$-v$&
this.beginIndex = beginIndex; <KL,G};0pm
} /T0F"e)Ci
61C7.EZZ;
/** FXG]LoP
* @return +>6iYUa
* Returns the currentPage. X9W@&zQ
*/ 5H<m$K4z
publicint getCurrentPage(){ ;"5&b!=t
return currentPage; %rL.|q9
} aFX=C>M
uP)'FI
/** 99e.n0
* @param currentPage V1N3iI
* The currentPage to set. 24 ' J
*/ r=
`Jn6@
publicvoid setCurrentPage(int currentPage){ we//|fA<
this.currentPage = currentPage; y@S$^jk.
} A4x]Qh3OO
,aZ[R27rpL
/** ?=Z?6fw
* @return @1roe
G
* Returns the everyPage. HAdg/3Hw
*/ l
^0@86
publicint getEveryPage(){ L\J;J%fz.
return everyPage; ~g]Vw4pv
} zFfr.g;L
I{C
SH
/** oWT3apGO
* @param everyPage vH@ds
k
* The everyPage to set. PO:{t
*/ Rsm^Z!sn
publicvoid setEveryPage(int everyPage){ 6Pl<'3&
this.everyPage = everyPage; Gx/Oi)&/
} 6@5+m
0`u3
V~3a!-m\
/** kS);xA8s]
* @return $bR~+C
* Returns the hasNextPage. +{.WQA}z\
*/ cKI9#t_
publicboolean getHasNextPage(){ H/
HMm{4
return hasNextPage; lTgjq:mn
} U?Zq6_M&
PJ%C N(0
/** ;A'mB6?%H
* @param hasNextPage i-_mTY&M
* The hasNextPage to set. %ntRG!
*/ Xl#ggub?
publicvoid setHasNextPage(boolean hasNextPage){ L L~%f
&_
this.hasNextPage = hasNextPage; :g0zT[f
} jV1.Yz(`
14yv$,
/** :4/3q|cn
* @return LU%E:i|
* Returns the hasPrePage. f.$af4
u
*/ qo bc<-
publicboolean getHasPrePage(){ /
zPO
return hasPrePage; ;?p>e'
} S4z;7z(8+
YU'E@t5
/** @#l= l
* @param hasPrePage d\8l`Krs[_
* The hasPrePage to set. x'<X!gw
*/ )3EY;
publicvoid setHasPrePage(boolean hasPrePage){ igPX#$0XU
this.hasPrePage = hasPrePage; oZ|\vA%4^
} `d}2O%P
/*mI<[xb
/** 8&slu{M-
t
* @return Returns the totalPage. X
l5 A
'h
* kt:!
7
*/ EaN6^S=
publicint getTotalPage(){ -[.[>&`/
return totalPage; ?6WY:Zec@
} h2d(?vOT
T_4/C2
/** /gP+N2o+}
* @param totalPage }5"u[Z.
* The totalPage to set. J)-x!y>
*/ KbeC"mi
publicvoid setTotalPage(int totalPage){ H/M@t\$Dc
this.totalPage = totalPage; Pd Wx|y{%
} >4CbwwMA
eJ-nKkg~a
} fz
"Y CHe
.Z *'d
=t?F6)Q
w``U=sfmV
Qo|\-y-#
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 *s3/!K
4j^
@wV'
个PageUtil,负责对Page对象进行构造: ;RlxD 4p
java代码: G18b$z
^U/O!GK
do'GlU oMC
/*Created on 2005-4-14*/ <N~K;n
v
package org.flyware.util.page; O;3>sLgc
=7UsVn#o
import org.apache.commons.logging.Log; -XG@'P_
import org.apache.commons.logging.LogFactory; }^\oCR@
6ik$B
/** .T`%tJ-Em
* @author Joa 1_G^w
qk
* 'V>-QD%1
*/ {P-):
publicclass PageUtil { |Y.?_lC
c &c@M$
privatestaticfinal Log logger = LogFactory.getLog %BQ`MZ
Q,Eo mt
(PageUtil.class); gRzxLf`K
"<gOzXpa
/** * v#o
* Use the origin page to create a new page nJ;.Td
* @param page cWm$;`Q#\
* @param totalRecords 8 zb/xP>
* @return 7xR\kL.,
*/ NxILRKwO
publicstatic Page createPage(Page page, int ~.|_ RdN
9-
#R)4_
totalRecords){ CvdN"k
return createPage(page.getEveryPage(), cz$2R
[D1Up
page.getCurrentPage(), totalRecords); W@esITr
} Uw:"n]G]D?
d_P` qA
/** rmOj
* the basic page utils not including exception E*lxVua
eJX#@`K
handler Alq(QDs
* @param everyPage L RF103nw
* @param currentPage h
yIV.W/
* @param totalRecords phz&zlD
* @return page |l!aB(NW
*/ P2nu;I_&
publicstatic Page createPage(int everyPage, int `0R./|bv\I
d"Y{UE
currentPage, int totalRecords){ t`QENXA}
everyPage = getEveryPage(everyPage); K<J9~
currentPage = getCurrentPage(currentPage); LIrb6g&xj_
int beginIndex = getBeginIndex(everyPage, UCWBYC+
?@8[e9lLD
currentPage); &m vSiyKX
int totalPage = getTotalPage(everyPage, DV{=n C
wyG;8I
totalRecords); nRY5xRvK
boolean hasNextPage = hasNextPage(currentPage, .wr>]yN
dqAw5[qMJ
totalPage); BerwI
7!=
boolean hasPrePage = hasPrePage(currentPage); {>;R?TG]$
&.ACd+Cd
returnnew Page(hasPrePage, hasNextPage, et+0FF
,
everyPage, totalPage, ?fS9J
currentPage, A)~6Im
I2DpRMy
beginIndex); 9>$p
} 2+O'9F_v
|'2d_vR
privatestaticint getEveryPage(int everyPage){ LHmZxi?
return everyPage == 0 ? 10 : everyPage; C.QO#b
} F5#YOck&,
"h ^Z
privatestaticint getCurrentPage(int currentPage){ Qci]i)s$js
return currentPage == 0 ? 1 : currentPage; bjS{(
} (I}v[W
Qei"'~1a
privatestaticint getBeginIndex(int everyPage, int XZwK6F)L
BPHW}F]X
currentPage){ D3A/l
return(currentPage - 1) * everyPage; u-C)v*#L
} d5l UGRg
_tXlF;
privatestaticint getTotalPage(int everyPage, int M@ZI\
]:\dPw`A
totalRecords){ uwBiW
int totalPage = 0; #o2[hibq
1i] ^{;]
if(totalRecords % everyPage == 0) Tb-F]lg$
totalPage = totalRecords / everyPage; UY2O Z&&
else yiI1x*^
totalPage = totalRecords / everyPage + 1 ; 3yXY.>'
]0\MmAJRn
return totalPage; t()c=8qF|u
} dq[xwRU1
DFTyMB1H
privatestaticboolean hasPrePage(int currentPage){ <