Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 1o"y%*"
WzNG<rG
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 R|cFpRe
PaU@T! v
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 t*ri`}a{v
|hZ|+7
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 %-0em!tUV
[:/7OM
。 /cn/[O9
b[QCM/
分页支持类: Vj9`[1}1Z
#b<lt'gC
java代码: T-<> )N5y
uv_P{%TK
s%0[DO3NV
package com.javaeye.common.util; g,{Ei]$>I
: .UX[!^
import java.util.List; k;AV;KWI'
3P<Zzt%e T
publicclass PaginationSupport { ^*4(JR
?45K%;.9Q
publicfinalstaticint PAGESIZE = 30; T3B|r<>I
J$e Z Lj
privateint pageSize = PAGESIZE; ^$Me#ls!
oPC IlH
privateList items; P+_\}u;
ijR*5#5h
privateint totalCount; bb0{-T)1
Z7k1fv:S^
privateint[] indexes = newint[0]; ~Krg8s!F&
WZDokSR
privateint startIndex = 0; .D M1Knj
A~%g"
public PaginationSupport(List items, int sOrY^cY;
XEe+&VQmY
totalCount){ t9=|* =;9)
setPageSize(PAGESIZE); }I'>r(K
setTotalCount(totalCount); z!uB&2C{k
setItems(items); 55jY` b.
setStartIndex(0); -*-zU#2|
} ix_$Ok
LRLhS<9
public PaginationSupport(List items, int ?!Th-Cc&m
B'[3kJ '
totalCount, int startIndex){ _4x[}e7KF
setPageSize(PAGESIZE); nd*!`P
setTotalCount(totalCount); 3GuMiht5
setItems(items); Y/Gswcz
setStartIndex(startIndex); !x!L&p
} [fJFH^&?hr
VS@rM<K{
public PaginationSupport(List items, int 85d7IB{28
FKvO7? K
totalCount, int pageSize, int startIndex){ bvxxE/?Ni
setPageSize(pageSize); _sD]Viqc
setTotalCount(totalCount); 3M>FU4Ug2
setItems(items); pdXgr)Uv
setStartIndex(startIndex); 75BOiX
} Fr Q-v]c
c# 4ZDjvm6
publicList getItems(){ w7]p9B
return items; [.yx2@W
} PrYWha=c-
bNPjefBF
publicvoid setItems(List items){ VIlQzM;%^
this.items = items; )jQe K
} 4s+J-l
?28G6T]/?d
publicint getPageSize(){ TVEF+t
return pageSize; 2>_LX!kyP]
} ZkVvL4yIK
)]e d;V
publicvoid setPageSize(int pageSize){ QIxJFr;>
this.pageSize = pageSize; ]t!}D6p
} '-1jWw:8
<45dy5!Tz
publicint getTotalCount(){ 2K7:gd8Ru
return totalCount; aN);P>
} ]oZ,{Q5~
OuJy$e
publicvoid setTotalCount(int totalCount){ "%@=?X8
if(totalCount > 0){ GlkAJe]
this.totalCount = totalCount; RBp(dKxM$w
int count = totalCount / *Uw#
5]O LV1Xt
pageSize; T>:g
ME
if(totalCount % pageSize > 0) =v#A&IPA'
count++; J$=b&$I(
indexes = newint[count]; SoON@h/
for(int i = 0; i < count; i++){ /3:IE%o
indexes = pageSize * YdL1(|EdM
,EJ [I^
i; DD{@lM\vc
} e+[J[<8
}else{ A.cZa
this.totalCount = 0; z_iyuLRdb
} :^.8 7>V7
} j$ i8@]
wP *a>a
publicint[] getIndexes(){ FYE9&{]h
return indexes; !z6/.>QJ~
} 6'lT`E|
[q|Q]O0
publicvoid setIndexes(int[] indexes){ LRlk9:QD>
this.indexes = indexes; ^V;lZtZ
} Ognq*[om
q8yJW-GA
publicint getStartIndex(){ [g
68O*
return startIndex; K#pt8Q
} %!/liS
$TW+LWb
publicvoid setStartIndex(int startIndex){ G&@RLht
if(totalCount <= 0) vh{1u
this.startIndex = 0; QMfy^t+I
elseif(startIndex >= totalCount) *gMP_I
this.startIndex = indexes 9(gOk
MicVNs
[indexes.length - 1]; E$zq8-p|
elseif(startIndex < 0) we).8%)'
this.startIndex = 0; ]R.Vq\A%S
else{ :zy'hu;
this.startIndex = indexes f$*9J
U=1`. Ove
[startIndex / pageSize]; `U>b6{K
} ,OFr]74\
} MvwJ(3
K OHH74}_
publicint getNextIndex(){ dM;WG;8e
int nextIndex = getStartIndex() + 1+ARV&bc
42[:s:
pageSize; -Ce4px?3
if(nextIndex >= totalCount) cO?"
return getStartIndex(); R$,iDv.jI
else 03jBN2[!
return nextIndex; 5|={1Lp24g
} 0'2{[xF
%cif0Td
publicint getPreviousIndex(){ &!aLOx*3`
int previousIndex = getStartIndex() - 0r&9AnnWu+
yXQ;LQ;
pageSize; i(;u6Rk
if(previousIndex < 0) |>V>6%>vK6
return0; 'r <BaL
else dWWkO03|
return previousIndex; !oRm.cO
} D`ge3f8Wi
=ZL}Av}
} .
zMM86 c
7I3CPc$
!d@`r1t
)/^$JYz
抽象业务类 &x5ZEe4
java代码: P9chRy
r:Tb{cA
]xeyXw84k
/** V zx(J)
* Created on 2005-7-12 &_^<B7aC'k
*/ $
T_EsnN
package com.javaeye.common.business; r1?FH2Ns
Qz$Dv@*y\
import java.io.Serializable; 1! [bu
import java.util.List; Q]:%Jj2
&Rt]K
import org.hibernate.Criteria; 0PbIWy'
import org.hibernate.HibernateException; =5eDT~=2{U
import org.hibernate.Session; 2=
mD
import org.hibernate.criterion.DetachedCriteria; p&M'DMj+
import org.hibernate.criterion.Projections; #a l^Uqd
import 6-YR'ikU
Vb#@o) z
org.springframework.orm.hibernate3.HibernateCallback; R?Q-@N>wE
import AWNd(B2o
aRP+?}b">
org.springframework.orm.hibernate3.support.HibernateDaoS nU *fne?
]997`,1b
upport; K9Fnb6J$u
LK5H~FK
import com.javaeye.common.util.PaginationSupport; a][Z;g
:*nBo
public abstract class AbstractManager extends *s4!;2ZhsU
=^M t#h."
HibernateDaoSupport { j06oAer 9
Z9^$jw]
privateboolean cacheQueries = false; B K;w!]
dG$0d_Pq
privateString queryCacheRegion; .NC}TFN|
@S92D6
publicvoid setCacheQueries(boolean WcG&W>
Zi)8KO[/0
cacheQueries){ FI5C&d5d
this.cacheQueries = cacheQueries; c!T{|'?
} s~w+bwr
C^tC} n1D(
publicvoid setQueryCacheRegion(String "c*|vE
h;M2ylOu.
queryCacheRegion){ r8.v0b"1
this.queryCacheRegion = \LXC269
i%
lB
U1
queryCacheRegion; 1w^[Eno$$
} (RS:_]
+60;z4y}w
publicvoid save(finalObject entity){ .>&fwG
getHibernateTemplate().save(entity); [{*#cr f
} %C:XzK-x
0wcWDE
9
publicvoid persist(finalObject entity){ Q[KR,k
getHibernateTemplate().save(entity); Shd,{Z)-Tg
} }YO}LQ-|
+rY0/T_0,
publicvoid update(finalObject entity){ 6vA5;a@
getHibernateTemplate().update(entity); ;N|>pSzmL
} <k5~z(
RJ44o>L4O
publicvoid delete(finalObject entity){ i6kyfOI
getHibernateTemplate().delete(entity); d`/{0 :F
} cf'Z#NfQ
?Gfe?
publicObject load(finalClass entity, OpE+e4~IF
(?[cDw/{J:
finalSerializable id){ '3->G/Pu
return getHibernateTemplate().load N~d]}J8}gx
P|U>(9;P,
(entity, id); U?{j
} O=/Tx2i;
)Cl&"bX
publicObject get(finalClass entity, swA"_A8>u
W~FA9Jd'Z
finalSerializable id){ ](D [T
return getHibernateTemplate().get HfiM]^
|O?Aj1g[c?
(entity, id); &i!]
} )^+$5OR\c
0oMMJ6"i
publicList findAll(finalClass entity){ TW0^wSm
return getHibernateTemplate().find("from KK?~i[aL
9Ba<'wk/>"
" + entity.getName()); !%@{S8IP.v
} Gov{jksr
B!v1gh
publicList findByNamedQuery(finalString \m!."~%
6dUP's_
namedQuery){ urB.K<5ZA
return getHibernateTemplate zZHsS$/
j@2 hI,+
().findByNamedQuery(namedQuery); FzIA>njt
} o_n.,=/cZ
yw0uF
publicList findByNamedQuery(finalString query, ?`>yl4
dp"w=~53
finalObject parameter){ Me>'QVr
return getHibernateTemplate DI7trR`
9P$'ON'"
().findByNamedQuery(query, parameter); e1-=|!U7#
} y=Hl ~ev`9
($TxVFNT
publicList findByNamedQuery(finalString query, D 4wB
&~U
2H#vA
finalObject[] parameters){ /MC\!,K
return getHibernateTemplate tWFJx}H
"$&F]0
().findByNamedQuery(query, parameters); "<WSEs
} 2h!3[{M\
?H`LrL/k
publicList find(finalString query){ V1G]LM
return getHibernateTemplate().find !QovpO">z
)94R\f
(query); r%m2$vx#
} 2i)y'+s
Mx
}(w\\T
publicList find(finalString query, finalObject :Us-^zVr
x@~V975Y
parameter){ [~3p+
return getHibernateTemplate().find *)1,W+A5L
{IVqV6:
(query, parameter); m[pzu2R
} WJ*DWyd''
`uj`ixcR
public PaginationSupport findPageByCriteria =bzTfki
\Mi< ROp5
(final DetachedCriteria detachedCriteria){ N?XN$hwdZ
return findPageByCriteria ,]MX&]
mR^D55k
(detachedCriteria, PaginationSupport.PAGESIZE, 0); k#.co~kS
} @&+
1b=
<3bh-)
public PaginationSupport findPageByCriteria ~"N]%Cu
3,?y !
(final DetachedCriteria detachedCriteria, finalint saV `-#
Tla*V#:Ve
startIndex){ vBp5&*
return findPageByCriteria ?>_.~b~
-|lnJg4
(detachedCriteria, PaginationSupport.PAGESIZE, zM!*r~*k$
Fi#t88+1
startIndex); 7qk61YBLz
} ?9mY #_Of
T^'i+>F!w
public PaginationSupport findPageByCriteria ziOmmL(r
p,+~dn;=
(final DetachedCriteria detachedCriteria, finalint l>ttxYBa<d
Qi%A/~
pageSize, z 4-wvn<*
finalint startIndex){ t^'1Ebg
return(PaginationSupport) Uu(W62
y^
:x2P
getHibernateTemplate().execute(new HibernateCallback(){ [{ pc1U-
publicObject doInHibernate BK{8\/dg
ihn M`TpMJ
(Session session)throws HibernateException { (_T&2%
Criteria criteria = u-Vnmig9
r?Vob}'Pt]
detachedCriteria.getExecutableCriteria(session); dM') <lF
int totalCount = N%-nxbI\
[Y*UCFhI0
((Integer) criteria.setProjection(Projections.rowCount ubLLhf
S4_Y^
()).uniqueResult()).intValue(); o8,K1ic5#
criteria.setProjection k"Is.[I?^
i <bs{Cu_S
(null); h^s}8y
List items = _,}Ye,(^=
_i
8oWy1
criteria.setFirstResult(startIndex).setMaxResults \rJk[Kec
ZjcJYtD
(pageSize).list(); S("bN{7nE
PaginationSupport ps = & mWq'h
YS]RG/'
new PaginationSupport(items, totalCount, pageSize,
Oe27 3Y^e
,wV2ZEW}e
startIndex); %vksN$^
return ps; j% nd
} ~i
\69q%
}, true); ^K"`k43{
} ]?r8^L yZ4
i8{jMe!Sa
public List findAllByCriteria(final u4"+u"{d
itP_Vxo/H
DetachedCriteria detachedCriteria){ +]6 EkZO
return(List) getHibernateTemplate %%_90t
[bp"U*!9P
().execute(new HibernateCallback(){ 1.!(#I3
publicObject doInHibernate *<hpq)
2Zm*f2$xM
(Session session)throws HibernateException { fZZ!kea[
Criteria criteria = E'ZWSpP
N_>s2
detachedCriteria.getExecutableCriteria(session); Q>r Q/V
return criteria.list(); xv2;h4{<
} ;V;4#
}, true); ?YS`?Rr
} ]X5*e'
3EFk] X
public int getCountByCriteria(final QV't+)uUVo
y`BLIEI
DetachedCriteria detachedCriteria){ "7l}X{b
Integer count = (Integer) \yxr@z1_b
E,r PM
getHibernateTemplate().execute(new HibernateCallback(){ )#Id2b~
publicObject doInHibernate YMWy5 \
h {m]n!
(Session session)throws HibernateException { pM=vW{"I/
Criteria criteria = 2::T, Z
f`c z@
detachedCriteria.getExecutableCriteria(session); gR6:J
return AT%0i
OYKV*
criteria.setProjection(Projections.rowCount ]}B&-Yp
i et|\4A
()).uniqueResult(); +LyhF2
} 1a'JNe$
}, true); &Ls0!dWC
return count.intValue(); ~vXul`x
} 1eJ\CdI
} %ry>p(-pC(
K'tz_:d|
-L[K1;Xv"
bw4b'9cK
0'~?u '
M$GD8|*e
用户在web层构造查询条件detachedCriteria,和可选的 Dn@ n:m
VcP#/&B|
startIndex,调用业务bean的相应findByCriteria方法,返回一个 l9Vim9R5T
Ax\Fg
5
PaginationSupport的实例ps。 %cv%u6 b
ZLV~It&)
ps.getItems()得到已分页好的结果集 R|vF*0)>W
ps.getIndexes()得到分页索引的数组 ux }DWrR
ps.getTotalCount()得到总结果数 dlU=k9N-
ps.getStartIndex()当前分页索引 UX0tI0.tg
ps.getNextIndex()下一页索引 *iR`mZb
ps.getPreviousIndex()上一页索引 ] *Hz'
6nDx;x&Q
(lm/S_U$
L{=z}QO
i^>
RjR
<L`R!}
OJK/>
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 +VeLd+Q}
crT[;w
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 qm '$R3g
MhsG9q_%
一下代码重构了。 @@$
_TaI
oM VJ+#[x
我把原本我的做法也提供出来供大家讨论吧: =FKB)#N
-(2-zznZ
首先,为了实现分页查询,我封装了一个Page类: AE$)RhY`
java代码: upJishy&I
51&T`i
f8j^a?d|
/*Created on 2005-4-14*/ Glwpu-@X
package org.flyware.util.page; UWnH2
&A9+%kOk>
/** <Du*Re6g
* @author Joa VMHY.Rf
* 94R+S-|P
*/ $DVy$)a!u
publicclass Page { Yv;aQF"a
-lp_~)j^
/** imply if the page has previous page */ [ M'1aBx^
privateboolean hasPrePage; 8sg *qQ
wVvU]UT
/** imply if the page has next page */ w"e2}iE7
privateboolean hasNextPage; pr?/rXw
l{R)yTO
/** the number of every page */ ALv\"uUNu+
privateint everyPage; )ad-s
|WX4L7yrhK
/** the total page number */ jQDxbkIuzE
privateint totalPage; ,&9|Ac?$
5(W9J j]
/** the number of current page */ 3k/MigT
privateint currentPage; 5YCbFk^
jyC6:BNust
/** the begin index of the records by the current qL#R
XUTP
-bE|FFU
query */ >"[u.1J_'I
privateint beginIndex; YU`{
YszhoHYh
:Ls36E8f=
/** The default constructor */ BpC Sf.zZ
public Page(){ W1s|7
s,RS}ek~|
} 3:gk:j#
5Zov<+kE
/** construct the page by everyPage E=E<l?ob
* @param everyPage AM[:Og S
* */ Ef!F;D e)A
public Page(int everyPage){ ]'G7(Y\)f
this.everyPage = everyPage; d
!H)voX
} :NLN xK
*O;N"jf
/** The whole constructor */ Nm~#$orI|
public Page(boolean hasPrePage, boolean hasNextPage, u *<
(B
?Y9?x,x
QKO(8D 6+
int everyPage, int totalPage, I%Awj(9BS
int currentPage, int beginIndex){ _=MWt_A '3
this.hasPrePage = hasPrePage; hD*?\bBs0
this.hasNextPage = hasNextPage; D.!4i.)8}
this.everyPage = everyPage; $d"+Njd
this.totalPage = totalPage; bo2Od
this.currentPage = currentPage; RB"rx\u7K
this.beginIndex = beginIndex; Ie~~L U
} EkX6> mo
0#JBz\
/** R<=t{vTJ5
* @return QZlUUj\
* Returns the beginIndex. -AE/,@ \P
*/ DXt^Ym5Cv
publicint getBeginIndex(){ 1<83MO;
return beginIndex; 2XtQ"`)
} eG v"&kr
zN1;v6;
/** ,b4&$W].
* @param beginIndex ,zFN3NLtA
* The beginIndex to set. [xPE?OD
*/ A@ME7^w7
publicvoid setBeginIndex(int beginIndex){ D\R^*k@V
this.beginIndex = beginIndex; sn(}5;
} `9-Zg??8r
J$;)TI
/** H4,yuV
* @return )sHPIxHI
* Returns the currentPage. =m:W
*/ 7r>W r#
publicint getCurrentPage(){ DFonK{
return currentPage; UwU]l17~
} UL%ihWq
F?B=:8,}
/** #k)\e;,X
* @param currentPage ooQ( bF
* The currentPage to set. B^9 #X5!
*/ l&B'.6XKs
publicvoid setCurrentPage(int currentPage){ ~}w 8UO
this.currentPage = currentPage; H~Cfni;
} ^=G+]$ 8
9x!y.gx
/** _SqrQ
* @return 9[D7N
* Returns the everyPage. [78
.%b'
*/ %*OJRL`
publicint getEveryPage(){ ,)1e+EnV&
return everyPage; 1*h7L<#|mQ
}
6qlr+f
`t6L'%\
/** H[
q{R
* @param everyPage ;^]A@WN6_
* The everyPage to set. =HHg:"
*/ 1tdCzbEn+
publicvoid setEveryPage(int everyPage){ / 5Loj&!=
this.everyPage = everyPage; R`q!~8u
} Oe`t!&v
<Tf;p8#
/** z7C1&bGe
* @return =*jcO119L
* Returns the hasNextPage. S)yV51^B
*/ b`zf&Mn
publicboolean getHasNextPage(){ }c%y0)fL
return hasNextPage; ?C35
} ?M^t4nj
"Ycd$`{Vgt
/** <h9\ A&
* @param hasNextPage !$Z"\v'b
* The hasNextPage to set. EB<q.
*/ m{c#cR
publicvoid setHasNextPage(boolean hasNextPage){ -::%9D}P|
this.hasNextPage = hasNextPage; CN(4;-so)
} 46Nf|~
UmX[=D|
/** Oy$BR
<\
* @return avu,o
* Returns the hasPrePage. ;!?K.,N:N
*/ o"[bIXf-h
publicboolean getHasPrePage(){ ;4$C$r!t
return hasPrePage; b_yXM
} u,:`5*al{
Bw.&3efd
/** IviQ)hp
* @param hasPrePage Xf9%A2 iB
* The hasPrePage to set. o[hP&9>q
*/ rrYp^xLa`
publicvoid setHasPrePage(boolean hasPrePage){ PqLqF5`S
this.hasPrePage = hasPrePage; ;NE/!!
} &Q>'U6"%
nD\os[ 3
/** [dlH
t;S
* @return Returns the totalPage. .N&}<T[
* _9|@nUD
*/ "%*lE0Tx
publicint getTotalPage(){ *J5RueUG
return totalPage; |wQZ~Ux:
} ue<<Y"NR
P1 stL,
/** F
t/
x5
* @param totalPage s$x] fO
* The totalPage to set.
}TJ|d=
*/ X@U1Ri
publicvoid setTotalPage(int totalPage){ CL :M>(
this.totalPage = totalPage; Ag0_^
} 8p{
Gcz@ze
} z/k~+-6O
&\|<3sd(
ok%!o+nk.
Cnci%eo
A5<Z&Y[
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一
iLcadX
{))S<_yN
个PageUtil,负责对Page对象进行构造: OG7v'vmY
java代码: w*%$
lhp!
zB"
`i
EZQ+HECpK
/*Created on 2005-4-14*/ ~PW}sN6ppG
package org.flyware.util.page; iCRw}[[
<<5 :zlb
import org.apache.commons.logging.Log; |!5T+H{Sj
import org.apache.commons.logging.LogFactory; 9w;J7jgOT!
:;q_f+U
/** .y9rM{h}b
* @author Joa Fi%W\Y'
* ~Z6p3#
!o
*/ c_$&Uii
publicclass PageUtil { p[F=L P
Bye@5D
privatestaticfinal Log logger = LogFactory.getLog }"B? 8T@_~
tW"ptU^9)
(PageUtil.class); 1idjX"'
'oZn<c`
/** `W$0T;MPF
* Use the origin page to create a new page ?En|
_E_C
* @param page &Z;8J @
* @param totalRecords 'ag6B(0Z
* @return bL],KW;Q
*/ s/vOxGc
publicstatic Page createPage(Page page, int iSz@E&[X
m2q;^o:J
totalRecords){ &xuwke:[
return createPage(page.getEveryPage(), U"y'Kd
_7.GzQJ
page.getCurrentPage(), totalRecords); 6(^Upk=59
} )):22}I#
GHC?Tp
/** (<R\
* the basic page utils not including exception |5B,cB_
p/WH#4Xdr
handler 8
]06!7S}
* @param everyPage *tfDXQ^mN
* @param currentPage 1;kG[z=A
* @param totalRecords PBww
* @return page ciGpluQF
*/ N!Wq}#&l
publicstatic Page createPage(int everyPage, int N'
$DE
v7<S F
currentPage, int totalRecords){ Prb_/B Dd
everyPage = getEveryPage(everyPage); t#pqXY/;D
currentPage = getCurrentPage(currentPage); a;'E}b{`F
int beginIndex = getBeginIndex(everyPage, x #X#V\w=
A6UdWK
currentPage); a}qse5Fr
int totalPage = getTotalPage(everyPage, M`+e'vdw
!P60[*>
totalRecords); _E1]cbIo
boolean hasNextPage = hasNextPage(currentPage, Hdbnb[e
UK~B[=b9
totalPage); 9p\Hx#^
boolean hasPrePage = hasPrePage(currentPage); 7hN6IP*so
K[LVT]3 n
returnnew Page(hasPrePage, hasNextPage, q"LJwV}W
everyPage, totalPage, y }&4HrT&
currentPage, <% 7P
}y-;>i#m=g
beginIndex); ^0x.'G?
} j`|^s}8t
Ld}(*-1i
privatestaticint getEveryPage(int everyPage){ Fi?Q
4b
return everyPage == 0 ? 10 : everyPage; N?=qEX|R
} ?dKa;0\
2 ]DCF
privatestaticint getCurrentPage(int currentPage){ eN|HJ=
return currentPage == 0 ? 1 : currentPage; `b.o&t$L
} qaMZfA
IglJEH[+
privatestaticint getBeginIndex(int everyPage, int H#|Z8^ *Ds
A
eGG
currentPage){ KI Plb3oh
return(currentPage - 1) * everyPage; TvWU[=4Yk
} +\k9w.[:/
UR/qVO?
privatestaticint getTotalPage(int everyPage, int _<%\h?W$
)+w/\~@
totalRecords){ qJX+[PJ
int totalPage = 0; B3cf] S%
R?bn,T>
if(totalRecords % everyPage == 0) GcZM+ c
totalPage = totalRecords / everyPage; l~fh_IV1
else xgtJl}L
totalPage = totalRecords / everyPage + 1 ; B%eDBu
")
$(KIB82&
return totalPage; ?@lx
} j(Fa=pi
/zl3&~4
privatestaticboolean hasPrePage(int currentPage){ OAW=Pozr9
return currentPage == 1 ? false : true; jiwpDB&