Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 0EU4irMa
V@-GQP1
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 RE$-{i
/*HSAjv
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 H9!*DA<W
boovCW
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 S@($c'
b"bj|qF~E
。 Av]N.HB$
f+AIxSw
分页支持类: 2GS2,
"ZW*O{
java代码: )\G#[Pc7
t]%R4ymV
HX*U2<^
package com.javaeye.common.util; 3$;v# P$%N
hJNA%
import java.util.List; ohk =7d.'
f`J"A:
publicclass PaginationSupport { -. {7;6:(k
,CF~UX%
bU
publicfinalstaticint PAGESIZE = 30; ^KR(p!%
p?nVPTh
privateint pageSize = PAGESIZE; u\?u}t v
1sA-BQL
privateList items; bNgcZ
V.
9z}kkYk
privateint totalCount;
ond/e&1
iJeT+}
privateint[] indexes = newint[0]; }clNXtN
5]+eLKXB
privateint startIndex = 0; &>{L"{
| 'G$}]H
public PaginationSupport(List items, int v}@6"\
2&#iHv
totalCount){ 30"G%DFd
setPageSize(PAGESIZE); +P.Ir
setTotalCount(totalCount); ;ecF~-oku
setItems(items); Elx bHQj6
setStartIndex(0); 8~&v\GDkF
} Xw)+5+t"{
s]OXB {M
public PaginationSupport(List items, int 0@;E8^pa
m^KkS
totalCount, int startIndex){ ?zqXHv#x
setPageSize(PAGESIZE); Gr?gHAT
setTotalCount(totalCount); :;QLoZh^
setItems(items); [MG:Ym).2`
setStartIndex(startIndex); m`aUz}Y>c
} JG4I-\+H
F!8425oAw
public PaginationSupport(List items, int F{Hy@7
d[de5Xra
totalCount, int pageSize, int startIndex){ 0c)19Ig
setPageSize(pageSize); YQJ_t@0C
setTotalCount(totalCount); []NAV
setItems(items); s!Vtwp9
setStartIndex(startIndex); V,}cDT>
} uIBV1Qz
lM]7@A
publicList getItems(){ a*`J]{3G
return items; $[e*0!e
} r@aFB@
k9
E?5
publicvoid setItems(List items){ ruVm8BO
this.items = items; K\PS$
} x($1pAE
gV0ZZ"M
publicint getPageSize(){ Ff30%
return pageSize; IU/*YI%W
}
NDi@x"];
S5vJC-"
publicvoid setPageSize(int pageSize){ mc$dR,
H0
this.pageSize = pageSize; Sw~<W%! ?
} h 9/68Gc?6
yL1\V7GI{[
publicint getTotalCount(){ O;r8l+
return totalCount; #0tM88Wi
} =`")\?z}
4*]`s|fbu
publicvoid setTotalCount(int totalCount){ [@)|j=:i:
if(totalCount > 0){ 5UqCRz<,R
this.totalCount = totalCount; l6RJour
int count = totalCount / _]NM@'e
71eD~fNdx
pageSize; LQ._?35r
if(totalCount % pageSize > 0) 6K&V}
count++; 3e"G.0vJ
indexes = newint[count]; f7L |Jc
for(int i = 0; i < count; i++){ Xc.~6nYp
indexes = pageSize * h$3Y,-4
@/~41\=e
i; qe0@tKim
} {=kA8U
}else{ ITTC}
this.totalCount = 0; v^pE=f*/
} h^4oy^9
} ,Tpds ^
$W)FpN;CW/
publicint[] getIndexes(){ ?mMd6U&J
return indexes; 7be?=c)+"
} ) ":~`Z*@
}9'rTLM
publicvoid setIndexes(int[] indexes){ Jyn>:Yq(
this.indexes = indexes; nHhg#wR
} ='f>p+*c%
nWh?zf#{
publicint getStartIndex(){ Yq.Omr!
return startIndex; yRAb
HG,c
} {3?g8e]zr
E:%%Dm
publicvoid setStartIndex(int startIndex){ A%Ao yy4E
if(totalCount <= 0) NLj0\Pz|B
this.startIndex = 0; Z#0z #M`
elseif(startIndex >= totalCount) =,sMOJc>
this.startIndex = indexes {It4=I)M
6oC(09
[indexes.length - 1]; C>LkU |[
elseif(startIndex < 0) \Ew2@dF{O
this.startIndex = 0; 0tA+11Iu
else{ B^oXUEOImq
this.startIndex = indexes 4aGHks8Z,\
#fwG~Q(
[startIndex / pageSize]; Ts^IA67&<
} H|Eu,eq-E
} ,5nrovv
\aG>(Mr
publicint getNextIndex(){ 1=s%.0
int nextIndex = getStartIndex() + ]+oPwp;il
p%n}a%%I
pageSize; YoXXelO&
if(nextIndex >= totalCount) 0 {w?u %'
return getStartIndex(); t4nAy)I)P
else %_5B"on
return nextIndex; %H:!/'45
} WL>"hkx
Yx,
publicint getPreviousIndex(){ P
/Js!e<\
int previousIndex = getStartIndex() - RS$e^_ W
KktQA*G
pageSize; H4)){\
if(previousIndex < 0) sb;81?|
return0; f9!wO';P6
else ~6R|
a
return previousIndex; |n0 )s% 8`
} {BgGG@e
wAITE|H<zj
} 8c#u"qF
& %1XYpA.0
o-R;EbL
%c[by
抽象业务类 Lt_7pb%
java代码: T*z >A
2@=JIMtc
a(bgPkPP
/** "= HCP,
* Created on 2005-7-12 :H6Ipa
*/ <V9L
AWeS
package com.javaeye.common.business; 9Y~A2C
<s
$~h
import java.io.Serializable; d!8`}L:=M
import java.util.List; ]XU?Wg
;/$zBr`'
import org.hibernate.Criteria; z!eY=G'
import org.hibernate.HibernateException; p9Ks=\yvL
import org.hibernate.Session; 7`
&K=( .
import org.hibernate.criterion.DetachedCriteria; POdG1;)
import org.hibernate.criterion.Projections; 5PG%)xff*
import fH>]>2fS
jg#%h`
org.springframework.orm.hibernate3.HibernateCallback; lQldW|S>
import $TWt[
:FB#,AOa_
org.springframework.orm.hibernate3.support.HibernateDaoS &p0*:(j
~[Mm0L}8
upport; kpcIU7|e
(@~d9PvB>
import com.javaeye.common.util.PaginationSupport; !XQG1!|ww
MJb!+E+
public abstract class AbstractManager extends Uk5jZ|
)9,9yd~SI
HibernateDaoSupport { UuW"
Ydh]EO0'
privateboolean cacheQueries = false; h0L*8P`t
[P407Sa"
privateString queryCacheRegion; h]&8hl_'m
xn}sh[<:P
publicvoid setCacheQueries(boolean B<x)^[ <v
k~h'`(
cacheQueries){ A2!7a}*1(
this.cacheQueries = cacheQueries; 94LFElE3
} '*|Wi}0R
t=Tu-2,k
publicvoid setQueryCacheRegion(String ]HCu tq
zaf%%
queryCacheRegion){ S8^W)XgC;
this.queryCacheRegion = D^$Nn*i;U
Y[#i(5w
queryCacheRegion; H0_hQ:K
} eo4;?z
1@im+R?a
publicvoid save(finalObject entity){ Pl9/1YhD/
getHibernateTemplate().save(entity); 9U^jsb<St>
} aj85vON1`
e}D#vPaSY
publicvoid persist(finalObject entity){ XzIhFX6
getHibernateTemplate().save(entity); G BV]7.
} lZ'-?xo
+eg$Z]Lht
publicvoid update(finalObject entity){ 8lh{ R
getHibernateTemplate().update(entity); -=I*{dzly
} KFvNsqd
I6ffp!^}Y
publicvoid delete(finalObject entity){ l
2y_Nz-;
getHibernateTemplate().delete(entity); Zqc+PO3lw
} T}jryN;J5
JL=MlZ
publicObject load(finalClass entity, k.NgE/;3
J*IC&jH:
finalSerializable id){ t
5g@t0$
return getHibernateTemplate().load wK!4:]rhG
uW},I6g
(entity, id); Y1vl,Yi
} u|z B\zd
$fR[zBxA
publicObject get(finalClass entity, ^&>(_I\w.6
UEbRg =6
finalSerializable id){ F
0q#.
return getHibernateTemplate().get +q[puFfl
a=>PGriL
(entity, id); <nOK#;O)
} ~&8ag`
pn<M`,F~q
publicList findAll(finalClass entity){ x >hnH{~w
return getHibernateTemplate().find("from ep* (
%}t.+z(S
" + entity.getName()); dcew`$SJp
} h(*!s`1
{ AdPC?R`
publicList findByNamedQuery(finalString gpB3\
GdVq+,Ge
namedQuery){ ]-FK6jw
return getHibernateTemplate uU=O 0?'zq
a*@ 6G
().findByNamedQuery(namedQuery); Y;JV9{j
} <iDqt5)N
R]L|&{
publicList findByNamedQuery(finalString query, `Hld#+R
O RAKg.49
finalObject parameter){ M[Lj N
return getHibernateTemplate z'GYU=
v0&E!4q*'
().findByNamedQuery(query, parameter); 794V(;sW,
} rP Wn
^dj
avJ
publicList findByNamedQuery(finalString query, Q{F*%X
q'{LTg0kk
finalObject[] parameters){ 3eX;T +|o
return getHibernateTemplate |7KW'=O
PZmg7N
().findByNamedQuery(query, parameters); ('BFy>@
} OLp;eb1g
cD5c&+,&I
publicList find(finalString query){ (lBgWz
return getHibernateTemplate().find hDTiXc
:d\ne
(query); 1D159 NLB
} 3}V`]B#a
AvnK?*5!@
publicList find(finalString query, finalObject MW*@fl<@?M
+c$]Q-(
parameter){ h.+{cOA;n
return getHibernateTemplate().find No#1Ik w
%GG:F^X#
(query, parameter); t '
_Au8
} f6@fi`U,
n<\
WVi
public PaginationSupport findPageByCriteria xLhN3#^m
&0! f_
(final DetachedCriteria detachedCriteria){ 4Rj;lAlwB
return findPageByCriteria ,5`pe%W7
~H"Q5Hr
(detachedCriteria, PaginationSupport.PAGESIZE, 0); m!{Xu y
} M5DQ{d<r
Nb;xJSl ox
public PaginationSupport findPageByCriteria l,5<g-r
V
l+g\xUP
(final DetachedCriteria detachedCriteria, finalint owHV&(Go(B
H6i4>U*
startIndex){ itV@U
return findPageByCriteria {!h|(xqN+
M\\t)=q
(detachedCriteria, PaginationSupport.PAGESIZE, ;o*n*N
1haNca_6,
startIndex); mRVE@pc2X
} =xzDpn>f
z/09~Hc
public PaginationSupport findPageByCriteria ]XX9.Xh=-
6~g`B<(?
(final DetachedCriteria detachedCriteria, finalint c|?0iN
v[4A_WjT
pageSize, $qOV#,@
finalint startIndex){ |Yq0zc!
return(PaginationSupport) C/AqAW1
m]LR4V6k|
getHibernateTemplate().execute(new HibernateCallback(){ rz/^_dV
publicObject doInHibernate qIE e7;DO
xe ng`!
(Session session)throws HibernateException { 1NJ,If]
Criteria criteria = [4Tiukk(
5cLq6[uO
detachedCriteria.getExecutableCriteria(session);
Z|zyO-
int totalCount = `-qRZh@ E
{c5%.<O
((Integer) criteria.setProjection(Projections.rowCount m?LnO5Vs
Gd^K,3:. T
()).uniqueResult()).intValue(); LvP{"K;
criteria.setProjection |KSd@
N$#518
(null); 4-lG{I_S:
List items = 9e^HTUFbG
$x_6
.AOZ,
criteria.setFirstResult(startIndex).setMaxResults _m3}0q
ch2Q k8
(pageSize).list(); H(f~B<7q
PaginationSupport ps = .-Y3oWV
S<),
,(
new PaginationSupport(items, totalCount, pageSize, FtBYPSGz
XP#j9CF#.
startIndex); 7kDX_,i
return ps; dV+%x"[:
} Cm)_xnv
}, true); fa#xEWaFr
} b'i-/l$
B<)c{kj
public List findAllByCriteria(final oy+`` W~
/JaCbT?*T
DetachedCriteria detachedCriteria){ BGAqg=nDV
return(List) getHibernateTemplate QEd>T"@g
&n:3n
().execute(new HibernateCallback(){ )Rhy^<xH
publicObject doInHibernate s"1:#.u
iCA!=%M@D
(Session session)throws HibernateException { Yr9>ATR
Criteria criteria = Twscc"mK
c*0pF=3
detachedCriteria.getExecutableCriteria(session); T(UdV]~]"
return criteria.list(); -9Iz$(>a
} I_vPGafMx
}, true); w7n6@"q
} M9mC\Iz[
M7D@Uj&xx(
public int getCountByCriteria(final ]7H ?
&S\q*H=}i
DetachedCriteria detachedCriteria){ @WcK<Qho
Integer count = (Integer) n<Vq@=9AE
WxNPAJ6YH
getHibernateTemplate().execute(new HibernateCallback(){ 6k?,'&z|~
publicObject doInHibernate z}XmRc_Ko
<hG=0Zc r
(Session session)throws HibernateException { KIt:ytFx
Criteria criteria = dQhh,}
w&6c`az8
detachedCriteria.getExecutableCriteria(session); EBF608nWfW
return Koh`|]N
@8[3]<
criteria.setProjection(Projections.rowCount
OC0dAxq
x9fNIuAQ
()).uniqueResult(); 1.+w&Y5
} e;LJdd
}, true);
!'-K>.B
return count.intValue(); NZUQ
R`5
} A0L&p(i
} q2qbbQ6H
K \?b6;ea
vj?v7
^G5BD_
}lN@J,q
5k&tRg
用户在web层构造查询条件detachedCriteria,和可选的 +APf[ZpU
I]S8:w![
startIndex,调用业务bean的相应findByCriteria方法,返回一个 %lL^[`AR
mDn*v(
f
PaginationSupport的实例ps。 R-v99e iN
^:JZ.r
ps.getItems()得到已分页好的结果集 F"7dN *7
ps.getIndexes()得到分页索引的数组 eURy]
ps.getTotalCount()得到总结果数 ]k2Jf}|
ps.getStartIndex()当前分页索引 jI`1>>N&1
ps.getNextIndex()下一页索引 aBV{Xr~#(
ps.getPreviousIndex()上一页索引 %m\dNUz4g
,^dyS]!d$
SoS GQ&k
vo'=d"zm
yn;h.m [):
V?{[IMRC
+.i?UHNB
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 J{98x zb
=F>@z4[P-
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 P#`Mg@.
< 8yv(
一下代码重构了。 +-=o16*{ !
p h[
^ve
我把原本我的做法也提供出来供大家讨论吧: z"`q-R }m
3`9H
首先,为了实现分页查询,我封装了一个Page类: ]6wo]nV[P
java代码: eQBR*@x
I+ZK \?Rs
=ytB\e
/*Created on 2005-4-14*/ 5w:
package org.flyware.util.page; yGN@Hd:9
^X$k<n A;
/** igNZe."V
* @author Joa 2i+'?.P
* &<</[h/B/F
*/ ~T<yp
publicclass Page { EC6)g;CO
kj(Ko{
/** imply if the page has previous page */ ,3^gB,ka
privateboolean hasPrePage; 0>#or$:6E
x Bn+-V
/** imply if the page has next page */ Qz*!jwg
privateboolean hasNextPage; H ]BH
Yh%a7K
/** the number of every page */ \k?uh+xl
privateint everyPage; wRwTN"Yg
e/@t U'$
/** the total page number */ WB S~e
privateint totalPage; hdB.u^!
L%,tc~)A
/** the number of current page */ Y)@mL~){
privateint currentPage; b-}nv`9C
>h3r\r\n3
/** the begin index of the records by the current +dWx?$n
K\5'pp1
query */ : `D[0
privateint beginIndex; l#P)9$%
LM:|Kydp3
_is<.&f6
/** The default constructor */ 74*1|S<
public Page(){ }]w/`TF
e|:#Y^
} N>z<v\`
b2;+a(
/** construct the page by everyPage k/+-Tq;
* @param everyPage u|m>h(O
* */ A^+G
w\
public Page(int everyPage){ fFD:E} >5
this.everyPage = everyPage; ?haN ;n6'
} Y40Hcc+Fx
[jl'5l d
/** The whole constructor */ Uf^zA/33
public Page(boolean hasPrePage, boolean hasNextPage, Kg0Vbzvb
G_E U/p<Q
~.qzQ_O/
int everyPage, int totalPage, H"PnX-fGN
int currentPage, int beginIndex){ m=&j2~<i
this.hasPrePage = hasPrePage; ODn6%fp%
this.hasNextPage = hasNextPage; rK%<2i
this.everyPage = everyPage; O!+LM{>
F
this.totalPage = totalPage; M7"I]$|\
this.currentPage = currentPage; V>}@--$c-r
this.beginIndex = beginIndex; ]PVPt,c
} k|W =kt$ P
'LZF^m _<<
/** b#h?O}
* @return Uq/#\7/rL
* Returns the beginIndex. Ui6f>0?
*/ (uG.s %I
publicint getBeginIndex(){ QF/A-[V
return beginIndex; 3nt&Sf
} =PXQX(_
n`";ctQT
/** fsa
* @param beginIndex D8P<mIu}Y
* The beginIndex to set. `_Bvaej?,
*/ |He,v/r
publicvoid setBeginIndex(int beginIndex){ l,}{Y4\G
this.beginIndex = beginIndex; KE\p|X i
} t ZUZNKODW
D$g|f[l
/** $M\|zUQu.
* @return g]|K@sm
* Returns the currentPage. j""I,$t
*/ )5Yv7x(K
publicint getCurrentPage(){ Z5juyzj
return currentPage; 7sECbbJT
} TQm x$
y3T-^
/** BcaMeb-Z
* @param currentPage kR%bdN
* The currentPage to set. =T5vu~[J/e
*/ xz#;F ,`ZR
publicvoid setCurrentPage(int currentPage){ #*uSYGdc
this.currentPage = currentPage; 65bLkR{0
} %Kd&A*
,]@ K6
/** q;3,}emg
* @return e*_8B2da
* Returns the everyPage. %+oWW5q7
*/ 96;17h$
publicint getEveryPage(){ xQ4D| &
return everyPage; g|*2O}<
} GF5WR e(E
!=C4=xv
/** <)y44x|S'
* @param everyPage (g,lDU[=
* The everyPage to set. Q\G8R^9j p
*/ Izq]nR
publicvoid setEveryPage(int everyPage){ "6/`
this.everyPage = everyPage; %C=^
h1t%
} 0S@O]k)
d;&'uiS
/** g~_cYy
* @return 24{!j[,q@
* Returns the hasNextPage. :kSA^w8
*/ =W)Fa6P3j(
publicboolean getHasNextPage(){ lJ@2N$w
return hasNextPage; 2<}^m/}
} q[{q3-W
/km^IH
/** s~Wj h7'
* @param hasNextPage ,>CFw-Nxu
* The hasNextPage to set. 9
O| "Ws>{
*/ 0'O; H[nrl
publicvoid setHasNextPage(boolean hasNextPage){ 5;{d*L
this.hasNextPage = hasNextPage; :)}iWKAse
} :T3I"
)
Ph.
/** k$kq|
* @return NGB%fJ
* Returns the hasPrePage. %Qc#v$;+J
*/ N'R^S98x
publicboolean getHasPrePage(){ ~/1kCZB
return hasPrePage; y [e$
} :~loy'
*v3/8enf
/** aNb=gjLpt
* @param hasPrePage
VVeO>j d
* The hasPrePage to set. X5U.8qI3
*/ L>$yslH;b
publicvoid setHasPrePage(boolean hasPrePage){ #(3w6l2
this.hasPrePage = hasPrePage; g#~ jF
} +]H9:ARI
+U&aK dQs
/** ?H1I,]Di
* @return Returns the totalPage. h!56?4,%Y
* Gxv@ a
*/ F.c`0u;=
publicint getTotalPage(){ bTZ/$7pp9
return totalPage; M$#zvcp
} i+T#z
G T#hqt'1x
/** ,(Fo%.j
* @param totalPage NylN-X7[#
* The totalPage to set. /s& xI
*/ QlIg'B6
publicvoid setTotalPage(int totalPage){ p3 I{
this.totalPage = totalPage; )0`;leli
} =IV_yor
Fh& `v0
} `g6XVa*%#
;k^wn)JE$
7a0ZI
`kIzT!HX
G_zJuE$V
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 aKS
2p3
HZCEr6}(
个PageUtil,负责对Page对象进行构造: L
q8}z-?
java代码: ~R-S$qizAC
Yo@>O98
1B=vrGq
/*Created on 2005-4-14*/ Da1BxbDeI
package org.flyware.util.page; =[(1u|H9
w/KHS#~
import org.apache.commons.logging.Log; 1g9Qvz3
import org.apache.commons.logging.LogFactory; W%b<(T;
%1SA!1>j
/** aq~hl7MTj
* @author Joa W?~G_4
* q,VJpqQ
*/ 3 1KMn
publicclass PageUtil { G/_#zIN`8M
s4P8PDhz
privatestaticfinal Log logger = LogFactory.getLog nlXg8t^G
MBs]<(RJZ
(PageUtil.class); WK0?$[|=r
\k0%7i[nZ/
/** PXm{GLXRS;
* Use the origin page to create a new page 2G:)27Q-
* @param page 7}-.U=tnP
* @param totalRecords v 2k/tT$t
* @return }$#e&&)n
*/ +mhYr]Z
publicstatic Page createPage(Page page, int =$Sf]L
(f5!36mz
totalRecords){ J|_&3@r
return createPage(page.getEveryPage(), ^M6v;8EU
[ik D4p=
page.getCurrentPage(), totalRecords); ?l`DkUo*j
} j(F%uUpN
QZef=
/** i0 {pm q
* the basic page utils not including exception x68J [; jm
lG>rf*ei~
handler #9O
*@
* @param everyPage u$[
'}z0:
* @param currentPage EAxg>}'1j
* @param totalRecords YNc%[S[u^1
* @return page ?|TVz!3
*/ ur={+0
y
publicstatic Page createPage(int everyPage, int 1c&/&6#5
Jx1oK
currentPage, int totalRecords){ 6[wej$u
everyPage = getEveryPage(everyPage); ~[Mk QJxe
currentPage = getCurrentPage(currentPage); &WN4/=QW-J
int beginIndex = getBeginIndex(everyPage, bB3Mpaw@
/@R|*7K;9
currentPage); 'Kxs>/y3
int totalPage = getTotalPage(everyPage, -en:81a#
WqqrfzlM
totalRecords); OJ8W'"`L&
boolean hasNextPage = hasNextPage(currentPage, NSHWs%Zc
NLw#b?%
totalPage); 'P32G?1C&p
boolean hasPrePage = hasPrePage(currentPage); g[*+R9'
#tN)OZA
returnnew Page(hasPrePage, hasNextPage, (S0MqX*
everyPage, totalPage, 'Fo*h6=
currentPage, #<0%_Ca
c.m '%4
beginIndex); +`kfcA#pi
} {5-4^|!
K8Gc5#OF
privatestaticint getEveryPage(int everyPage){ |@]J*Kh
return everyPage == 0 ? 10 : everyPage; 1lfkb1BM
} k6ERGQ9|I
Z/sB72K1
privatestaticint getCurrentPage(int currentPage){ P[ n`X
return currentPage == 0 ? 1 : currentPage; 3m#v|52oj
} Z66akr
r1EccY
privatestaticint getBeginIndex(int everyPage, int gR.zL>=_5e
yU\&\fD>j
currentPage){ \v9IbU*js
return(currentPage - 1) * everyPage; ~-GgVi*I
} *PMvA1eN=#
gZ
privatestaticint getTotalPage(int everyPage, int E:4`x_~qQ
uTA
/E9OY
totalRecords){ F)j-D(c4
int totalPage = 0; Fj"gCBaR
Y4){{bEp
if(totalRecords % everyPage == 0) A|CW4f,
totalPage = totalRecords / everyPage; 5xwztcR-
else Bt[`p\p@
totalPage = totalRecords / everyPage + 1 ; z!)_'A
SWUHHl
return totalPage; wg^#S
} &fdH
HN
m;WUp{'
privatestaticboolean hasPrePage(int currentPage){ j;<Yje&Wz
return currentPage == 1 ? false : true; -2o4v#d
} VxLq,$B76
(WR&Vt4R