Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 (#If1[L
=MxpH+spI
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 0iV;g`%
Yh$fQ:yi\&
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 drI\iae{^
<*_o0;h|
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 d+0^u(gc!8
JYQ.EAsr!
。 >nK%^T
TtZ}"MPZ
分页支持类: $R?@L
IkQe~;Y
java代码: _$5@uL{n"^
eIJ[0c b}
|kc@L`7s
package com.javaeye.common.util; Wxn#Rk#>
JCD?qeTg
import java.util.List; $it@>L8
!9D1
Fa
publicclass PaginationSupport { p31oL{D
WFem#hq
publicfinalstaticint PAGESIZE = 30; I|T7+{5z
l!:^6i
privateint pageSize = PAGESIZE; cJ2PI
n[P\*S
privateList items; V'I T1~
Zw#<E
=\
privateint totalCount; |mOMRP#'
:v)6gz(p
privateint[] indexes = newint[0]; b]i>Bv
7&foEJ3q
privateint startIndex = 0; @Z q[e
N571s
public PaginationSupport(List items, int ,56;4)cv
$UC {"0
totalCount){ X3yS5whd(
setPageSize(PAGESIZE); }LQC.!
setTotalCount(totalCount); qnXTNs
?b
setItems(items); |IN[uQ
setStartIndex(0); d@ (vg
} zN")elBi
X}W)3v
public PaginationSupport(List items, int ^1 ;BiQ
I .P6l*$
totalCount, int startIndex){ NbkK&bz
setPageSize(PAGESIZE); ;A"\?i Q
setTotalCount(totalCount); dp<$Zw8BE
setItems(items); vBoO'l9'M
setStartIndex(startIndex); 9yL6W'B!
} \=fh-c(J,
q:]Q% IC^
public PaginationSupport(List items, int O aaH$B
qrE0H
totalCount, int pageSize, int startIndex){ !iJipe5
setPageSize(pageSize); l!@ 1u^v2
setTotalCount(totalCount); (O0byu}
setItems(items); p[qg&VKB
setStartIndex(startIndex); yWY|]Pp
} J>h;_jA
EEwWucQ
publicList getItems(){ c1#+Vse
return items; GHG,!C
} 30d#Lq
Mk5RHDh
publicvoid setItems(List items){ $3\,h;y
this.items = items; YlKFw|=
} Y.-S=Y
T5e^J"
publicint getPageSize(){ W;TJenv
return pageSize; H1&RI4XC
} [.-a$J[4+F
-?fR|[\[U
publicvoid setPageSize(int pageSize){ CXAVGO'xw
this.pageSize = pageSize; ArXl=s';s4
} t9` Ed>a
Ct!S Tk[2
publicint getTotalCount(){ >lLo4M 3
return totalCount; A ~&+F>Z
} X"<|Z]w
@GeHWv
publicvoid setTotalCount(int totalCount){ Ep ">v>"
if(totalCount > 0){ bV6V02RF
this.totalCount = totalCount; 2Y+:,ud\
int count = totalCount / ri=+(NKo-
D#0O[F@l##
pageSize; 1~Mn'O%
if(totalCount % pageSize > 0) y6%<zhs
count++; #PFO]j!_b
indexes = newint[count]; uJ8{HB
for(int i = 0; i < count; i++){ ChE_unw
indexes = pageSize * XwPx9+b6j
hY=I5[*
i; (>AFyh&3,X
} Dbz]{_Y;
}else{ 0roCP=;
this.totalCount = 0; QO,+ps<
} Ac\W\=QvB
} <|H?gfM
m UgRm]
publicint[] getIndexes(){ OKPJuV`y6
return indexes; _tWE8r,
} GV6mzD@<
&J(!8y*QyE
publicvoid setIndexes(int[] indexes){ v3-?CQb(
this.indexes = indexes; I%xn,u
} 6N3@!xtpi
*Hunp Y
publicint getStartIndex(){ *s\sa+2al
return startIndex; /80YZ
} .'lN4x
SdI1}&
publicvoid setStartIndex(int startIndex){ P4 6,o
if(totalCount <= 0) ~ 5"J(
this.startIndex = 0; j)L1H*
S%
elseif(startIndex >= totalCount) /s`;9)G]9
this.startIndex = indexes %g w{[
/[A
g^j7@dum
[indexes.length - 1]; 784;]wdy\
elseif(startIndex < 0) RGp'b
this.startIndex = 0; gp/YjUH7k8
else{ n(R_#,Hs
this.startIndex = indexes sFElD
]|
)eR$:uO
[startIndex / pageSize]; x)R0F\_
}
~6d5zI4\
} plXG[1;&G
jONjt(&N
publicint getNextIndex(){ }cW#045es
int nextIndex = getStartIndex() + =l,#iYJP8
ML=z<u+
pageSize; ^:z7E1~
if(nextIndex >= totalCount) f3&/r
return getStartIndex(); |!Ists
else 5f_7&NxT
return nextIndex; 7\%$>< K
} 40.AM1Z0f
M/B/b<['
publicint getPreviousIndex(){ VDiOO
int previousIndex = getStartIndex() - DL4iXULNY
<V
S2]13
pageSize; SqqDV)Uih1
if(previousIndex < 0) J]\^QMX
return0; ^PQM;"
else os**hFPk;1
return previousIndex; j^I!6j=ZX
} CQ1 8%w6
Ja [#[BJ?
} X6kaL3L}
|Puj7Ru
0jTMZ<&zZ
j_c+.iET
抽象业务类 `M]BhW)
java代码: vgAFuQi(
5/(sjMB
a_%>CD${t
/** Q>%E`h
* Created on 2005-7-12 o9+Q{|r
*/ WZK
:.y
package com.javaeye.common.business; }`]]b+_b>@
#Fzb8Yo
import java.io.Serializable; 1eiw3WU;
import java.util.List; "tX7%(
h2;l1G,
import org.hibernate.Criteria; QgZJ`G--
import org.hibernate.HibernateException; vJThU$s-
import org.hibernate.Session; vZk9gGjk
import org.hibernate.criterion.DetachedCriteria; `^e*T'UPl
import org.hibernate.criterion.Projections; bd{\{[^S!
import K?YEoz'y[
eJaUmK:
org.springframework.orm.hibernate3.HibernateCallback; !Bj^i
cR
import y@ . b
4
FfSI n3
org.springframework.orm.hibernate3.support.HibernateDaoS r=\P!`{5
`oXg<tivU
upport; BA*&N>a
;qb Dbg
import com.javaeye.common.util.PaginationSupport; y/\ZAtnLo
;sQ20 B'
public abstract class AbstractManager extends f1\7vEE,
_yJ|`g]U3
HibernateDaoSupport { Ql8^]gbp+
%omu
privateboolean cacheQueries = false; |D+p$^L
!ew6
n
I
privateString queryCacheRegion; 2Pz 5f
D6:DrA:
publicvoid setCacheQueries(boolean kQ[Jo%YT?E
==` Pb
cacheQueries){ Wl
TpX`
this.cacheQueries = cacheQueries; WG\Q5k4Ba
} OPLl*bnf
f}blB?e
publicvoid setQueryCacheRegion(String wt\m+!u`
y9ip[Xn-$:
queryCacheRegion){ =h7[E./U1
this.queryCacheRegion = |?yE^$a
xD^wTtT
queryCacheRegion; )@,N7Y1h
} IywiCMjH
V8T#NJ
publicvoid save(finalObject entity){ S*s:4uf
getHibernateTemplate().save(entity); J@gm@ jLc
} K4Y'B
o4
$E @ouX?
publicvoid persist(finalObject entity){ jJ<;2e~OW
getHibernateTemplate().save(entity); (gDQ\t@3-
} ;t~*F#p(!
"]<w x_!+}
publicvoid update(finalObject entity){ 6+?wnp-
getHibernateTemplate().update(entity); G
~A$jStm
} H7}g!n?
>~^`5a`$uI
publicvoid delete(finalObject entity){ T?#s'd
getHibernateTemplate().delete(entity); nfa_8
} '(T mV#3
[\a:4vDAbi
publicObject load(finalClass entity, cB<O.@
]2PQ X4t0
finalSerializable id){ X'xUwT|_+
return getHibernateTemplate().load n_1jHJo
@wMQC\Z
(entity, id); @Jm.HST#S8
} %fBP:5%K
4?v$<=#21*
publicObject get(finalClass entity, r:73uRk
G LoiH#R
finalSerializable id){ {wHvE4F2
return getHibernateTemplate().get 2+o! o
^glX1 )
(entity, id); OgQntj:%lN
} {hM"TO7\
;*nh=w
publicList findAll(finalClass entity){ 9QC< E|
return getHibernateTemplate().find("from 9@Q&B+!
*^uGvJXF
" + entity.getName()); :Jm!=U%'Z
} 3Fgz)*Gu]
?P%|P
publicList findByNamedQuery(finalString %n4@[fG%K
&{BBxv)y
namedQuery){ ?THa5%8f
return getHibernateTemplate J}:&eS
We\KDU\n
().findByNamedQuery(namedQuery); #jOOsfH|k
} 40R"^*
\|blRm;
publicList findByNamedQuery(finalString query, 28ja-1dB
gU~
L@R_D
finalObject parameter){ n%n'1AUP:
return getHibernateTemplate "oHp.$+K
xm^N8
().findByNamedQuery(query, parameter); hI*`> 9l
} |y klT
b/z'`?[
publicList findByNamedQuery(finalString query, 4{Q$!O>
U7jhV,gO4
finalObject[] parameters){ kp'b>&9r
return getHibernateTemplate F|6
nwvgq
";75 6'>
().findByNamedQuery(query, parameters); JR])xPI`
} Kq$:\B)<c
cD5w| rm?i
publicList find(finalString query){ ES^NBI j5P
return getHibernateTemplate().find hK
Fk$A
bAN 10U
(query); E2h(w_l
} 15o9CaQw4"
:DDO=
publicList find(finalString query, finalObject *U:VM'a
G aha Z
F
parameter){ oN_S}o
return getHibernateTemplate().find kea e.6[
?Y%}(3y
(query, parameter); @ <|6{N<
} sf
fV.cC`
"v@);\-V
public PaginationSupport findPageByCriteria @8QFP3\1
R_t~UTfI;
(final DetachedCriteria detachedCriteria){ &Q2NU$
return findPageByCriteria yVT&rQ"{
pi|\0lH6W
(detachedCriteria, PaginationSupport.PAGESIZE, 0); ]gb _Nv
} cZ6?P`X
NAJ '><2
public PaginationSupport findPageByCriteria :b.3CL\.6
a:=q8Qy
(final DetachedCriteria detachedCriteria, finalint $[)6H7!U)
|Uc<;> l
startIndex){ X";TZk
return findPageByCriteria _2wAaJvA
tX@0:RX%
(detachedCriteria, PaginationSupport.PAGESIZE, ]^Sd9ba
Tw2Xe S
startIndex); 0Ulxp
} :8](&B68gE
@m5O{[euj<
public PaginationSupport findPageByCriteria Y=AH%Gy9)
bjuYA/w<
(final DetachedCriteria detachedCriteria, finalint AqKHjCI
| -JI`!7
pageSize, E7V38Z
finalint startIndex){ MomLda
V9Q
return(PaginationSupport) k}- "0>
mfj4`3:NV
getHibernateTemplate().execute(new HibernateCallback(){ lq;
publicObject doInHibernate /7c2OI=\
mk#>Dpy?
(Session session)throws HibernateException { r3n=<l!Jr
Criteria criteria = UAnB=L,.\
fx]\)0n
detachedCriteria.getExecutableCriteria(session); ~C%2t{"
int totalCount = 3yeK@>C
R1II k
((Integer) criteria.setProjection(Projections.rowCount VI(RT-S6
i6-wf Gs;
()).uniqueResult()).intValue(); >L#];|
criteria.setProjection aeEw#
OG0r4^6Ly
(null); 7xX;MB&
List items = lF0K=L
:Tlf4y:/w
criteria.setFirstResult(startIndex).setMaxResults *>EI2HX
8dV.nO
(pageSize).list(); $Sp*)A]E`
PaginationSupport ps = !Sh^LYqn
h`z2!F4
new PaginationSupport(items, totalCount, pageSize, kqj;l\N
<8}KEe4
startIndex); <f7?PAd
return ps; <9Lv4`]GU5
} bRx2
c
}, true); ?| D$#{^
} }wvwZ`5t
hu bfK~
public List findAllByCriteria(final b=6MFPbg
SZCF3m&pz
DetachedCriteria detachedCriteria){ LEYWH%y
return(List) getHibernateTemplate %1Vu=zCAW
f$:7A0
().execute(new HibernateCallback(){ _<Hb(z
publicObject doInHibernate Xjs21-t%
^L>MZA
?
(Session session)throws HibernateException { #Tr;JAzVjG
Criteria criteria = J xA^DH
[5>S-Z
detachedCriteria.getExecutableCriteria(session); `,F&y{A
return criteria.list(); s`$NW^']
} =gxgS<bde
}, true); 4^d+l.F
} #G'S
ve?
_myg._[
public int getCountByCriteria(final AyQS4A.s[
?b!CV
DetachedCriteria detachedCriteria){ tebWj>+1c
Integer count = (Integer) bYwI==3
b@nri5noBm
getHibernateTemplate().execute(new HibernateCallback(){ \>*MMe
publicObject doInHibernate b&\3ps
jF%)Bhn(
(Session session)throws HibernateException { W&fW5af9
Criteria criteria = @4 zi]v
&"U9X"8b
detachedCriteria.getExecutableCriteria(session); zWCW: dI
return r1[E{Tpz
RB S[*D
criteria.setProjection(Projections.rowCount GM)\)\kNF
3::3r}g
()).uniqueResult(); DhtU]w}
} !Iw{Y'
}, true); {]t\`fjrg
return count.intValue(); LK'S)Jk
} p)?qJ2c|
} K7t&fDI
mF6@Y[/B
*G%1_
!ol hZ
e5*5.AB6&
9f\aoVX
用户在web层构造查询条件detachedCriteria,和可选的 bE7(L
$UF
`c qH}2s#
startIndex,调用业务bean的相应findByCriteria方法,返回一个 nx!qCgo
e67c:Z
PaginationSupport的实例ps。 AijPN
"E@NZ*"u
ps.getItems()得到已分页好的结果集 [
4?cM\_u@
ps.getIndexes()得到分页索引的数组 4*p_s8> >
ps.getTotalCount()得到总结果数 9%p7B ~}E
ps.getStartIndex()当前分页索引 O:oU`vE
ps.getNextIndex()下一页索引 .u&&H_ UmE
ps.getPreviousIndex()上一页索引 KKeb ioW
SY!`a:It
4_6W s$x
<GL}1W"Ay
^%K1R;
>,w\lf9
rh:s
7
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 TTA{#[=7
d&PE,$XC
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 VYl_U?D
bqw/O`*wfN
一下代码重构了。 /t$+Af,}
htUy2v#V
我把原本我的做法也提供出来供大家讨论吧: h/0<:eZ*
w%i+>\tO
首先,为了实现分页查询,我封装了一个Page类: X_-Hrp!h
java代码:
rE1np^z7
xh+AZ3
"K}W^J9v
/*Created on 2005-4-14*/ @1pW!AdN
package org.flyware.util.page; zer&`Vr
JEK%yMj
/** M-&^
* @author Joa ?J^IAFy
* 'NQMZfz
*/ p?Z+z
publicclass Page { xWenKY,
bl:a&<F
/** imply if the page has previous page */ |:7EJkKZ
privateboolean hasPrePage; FT*yso:X/
6SW|H"!!
/** imply if the page has next page */ ND9n1WZ&x
privateboolean hasNextPage; _g^K$+F'}
CI~hmL0
/** the number of every page */ wS F!Xx0
privateint everyPage; #K<=xP
uZqu xu.
/** the total page number */ qHC*$v#.V?
privateint totalPage; ?{@!!te@3v
i#@ v_^ q
/** the number of current page */ gqO%^b)6
privateint currentPage; b.mjQ
TRr4`y%
/** the begin index of the records by the current zn2"swhq\V
>0g`U
query */ J[&
7,}
privateint beginIndex; OUBgBr
V:,3OLL*
X*0eN3o.
/** The default constructor */ C)&gL=O*$
public Page(){ _-|yCo
l(krUv
} GM9]>"#o\
+h gaBJy
/** construct the page by everyPage ?FY@fO?es
* @param everyPage bOdsMlJkN
* */ 3IU$
public Page(int everyPage){ yO$r'9?,*
this.everyPage = everyPage; K*HVn2OV
} &|'Kut?8
32iWYN
/** The whole constructor */ J#Ne:Aj_
public Page(boolean hasPrePage, boolean hasNextPage, PoBukOv
NR;S3-Iq(
z/P^-N>
int everyPage, int totalPage, A_6/umF[ZA
int currentPage, int beginIndex){
FM;;x(sg
this.hasPrePage = hasPrePage; 0f=N3)
this.hasNextPage = hasNextPage; j-I6QUd
this.everyPage = everyPage; 4Rrw8Bw
this.totalPage = totalPage; =CG!"&T
this.currentPage = currentPage; \K_!d]I {
this.beginIndex = beginIndex; N)
V7yo?
} Ybn=Gy
VxPTh\O*[
/** Y00i{/a 8
* @return Ivt)Eg
* Returns the beginIndex. ?VOs:sln
*/ nI|Lx`*v
publicint getBeginIndex(){ HkfSx rTgQ
return beginIndex; QAOk
} eHnei F
YV ZSKU
/** Ow($\,
* @param beginIndex g1hg`qBBW
* The beginIndex to set. yN WbI0a
*/ &>) `P[x
publicvoid setBeginIndex(int beginIndex){ A\PV@w%Ai
this.beginIndex = beginIndex; .f.j >
} sxC{\iLY%
g*w-"%"O
/** -%/,j)VKD
* @return <-oRhi4
* Returns the currentPage. (W}i287
*/ !g8.8(/t)
publicint getCurrentPage(){ d'g{K]=tF
return currentPage; 0| DG\&?
} D)/XP
!3X%5=#L4
/** k+m_L{#m5
* @param currentPage *> &N
t
* The currentPage to set. K_lCDiqG
*/ 0R%uVJG
publicvoid setCurrentPage(int currentPage){ {L2Gb(YLW
this.currentPage = currentPage; vS*0CR\
} @R-~zOv
)H37a
/** =VX<eV
* @return cnUU1Uz>
* Returns the everyPage. Nh7!Ah
*/ 1Sc~Vb|>
publicint getEveryPage(){ `bt)'ERO%#
return everyPage; .+JPtL
} e,j ?_p
L&gEQDPgq|
/** k~9Ywf
* @param everyPage $qyM
X[
* The everyPage to set. >G3J3P(
*/ OTFu4"]M
publicvoid setEveryPage(int everyPage){ o}^vREO
this.everyPage = everyPage; I3E8vi%B.
} iDkWW
`bi_)i6Low
/** fPk9(X;G!p
* @return o j4)7{
* Returns the hasNextPage. }HQT@&=
*/ Q]?J%P.
publicboolean getHasNextPage(){ +KwF
U
return hasNextPage; e[k;SSs
} >0;"qT
XY t8vJ
/** uF.\dY\xv
* @param hasNextPage r0$9c
* The hasNextPage to set. T I7Ty+s
*/ v,.n/@s|X
publicvoid setHasNextPage(boolean hasNextPage){ _~#C $-T
this.hasNextPage = hasNextPage; X9`C2fyVd
} :;#}9g9
w-Q 6
-
/** `_{'?II
* @return WO*WAP)n
* Returns the hasPrePage. -{amzyvLE
*/ me`$5Z`
publicboolean getHasPrePage(){ [;LPeO
return hasPrePage; \ g[f4xAV
} A[,"jh
Ug'nr
/** uu/7Ie
* @param hasPrePage 0@/E%T1c"
* The hasPrePage to set. m&z%kVsg]
*/ 7;s0m0<%~
publicvoid setHasPrePage(boolean hasPrePage){ :)V0zHo&(
this.hasPrePage = hasPrePage; hG3$ ]i9
} ~i&< !O&
ToXFMkwY
/** fF]&{b~wk
* @return Returns the totalPage. Gt%?[
* vFvu8*0
*/ i.dAL)V
publicint getTotalPage(){ P;91C'T-x
return totalPage; ]}Hv,a
} ^d$e^cU
AkQFb2|ir
/** ?}Ptb&Vk(
* @param totalPage o?hw2-mH
* The totalPage to set. VKfHN_m*
*/ \C\y'H5
publicvoid setTotalPage(int totalPage){ A)a+LW'=u
this.totalPage = totalPage; 4Jy,IKPp
} Ecl7=-y
"7g8 d
} V'h z1roe
.;v'oR1x5
o>rlrqr?_
aTL7"Myp
hahD.P<
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 SSM>
ID
@:&dOqQ
个PageUtil,负责对Page对象进行构造: MJR\ g3
java代码: ..{^"`FQ
^aM/BS\
5+"8q#X$
/*Created on 2005-4-14*/ <@ex})su
package org.flyware.util.page; LzSusjEW@
:<3;7R'5
import org.apache.commons.logging.Log; $zA[5}{ZtQ
import org.apache.commons.logging.LogFactory; q'-l;V|
jN{xpd
/** Jj!tRZT
* @author Joa ;HwJw\fo
* T
]nR
XW$
*/ Vw@x
publicclass PageUtil { 8r|
F7u%oLjr
privatestaticfinal Log logger = LogFactory.getLog %z_b/yG
5*'N Q010
(PageUtil.class); 6 FxndR;
UdgI<a~`k6
/** Uy'ZL(2
* Use the origin page to create a new page " yl"A4p
S
* @param page JKv4}bv
* @param totalRecords
n&{N't
* @return u"$HWB~@z
*/ 7#*CWh1BNO
publicstatic Page createPage(Page page, int . ihn@eg
I,Y^_(JW
totalRecords){ 4tu>~ vOE
return createPage(page.getEveryPage(), fBh|:2u
FOyfk$
page.getCurrentPage(), totalRecords); BrmFwXLP"
} WZ-{K"56
Ybiz]1d
/** Z+Zh;Ms
* the basic page utils not including exception %cjav
l_IX+4(@b|
handler D\~$6#B>>
* @param everyPage o6%f%:&
* @param currentPage ZlXs7
&_
* @param totalRecords {%}6d~Bg
* @return page D)$k{v#~
*/ wpMQ 7:j
publicstatic Page createPage(int everyPage, int SvrV5X
KAEpFobYo
currentPage, int totalRecords){ j`hbQp\`
everyPage = getEveryPage(everyPage); I=I%e3GEm
currentPage = getCurrentPage(currentPage); <xz-7EqbwX
int beginIndex = getBeginIndex(everyPage, P?ol]MwaB
z1A-EeT
currentPage); m5g: Q
int totalPage = getTotalPage(everyPage, oK[,xqyA
e+aQ$1^t
totalRecords); FJ.
:*K[
boolean hasNextPage = hasNextPage(currentPage, jH/%Z5iu
LM`#S/h
totalPage); 0kEq|k9
boolean hasPrePage = hasPrePage(currentPage); skArocs
RtEkd_2
returnnew Page(hasPrePage, hasNextPage, l'R`XGT
everyPage, totalPage, IMEoov-x
currentPage, +T;qvx6
;:1mv
beginIndex); OPh@H.)^
} $$>,2^qr&L
5<
nK.i,
privatestaticint getEveryPage(int everyPage){ 2Vr'AEIQ
return everyPage == 0 ? 10 : everyPage; q@>
m~R
} t')I c6.?i
Stx-(Kfn4
privatestaticint getCurrentPage(int currentPage){ l,8|E
return currentPage == 0 ? 1 : currentPage; ^jC0S[csw2
} ovVU%2o1b
}RK9Onh3G
privatestaticint getBeginIndex(int everyPage, int Jrl
xa3 [
>r Glj
currentPage){ SjU6+|l
return(currentPage - 1) * everyPage; m8`A~
} `;hBO#(H0}
Xb;`WE gC
privatestaticint getTotalPage(int everyPage, int 6P$q7G
8b
$7#
totalRecords){ .=D6<4#t
int totalPage = 0; :v48y.Ij7s
;W:Q}[
if(totalRecords % everyPage == 0) !%=k/|#
totalPage = totalRecords / everyPage; RmCR"~
else Vt>E\{@[t
totalPage = totalRecords / everyPage + 1 ; ]t<%>Z$
/ nRaxzf'
return totalPage; '?4[w]0J<
} O#k+.LU
nQC[[G*x
privatestaticboolean hasPrePage(int currentPage){ o!d0
return currentPage == 1 ? false : true; rkp0ej2-
} Su^Z{ Ud`
3e:y?hpeL
privatestaticboolean hasNextPage(int currentPage, i[lH@fJm_
O%{>Zo_<