Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 k-vxKrjZ/
X{riI^(
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 r\66]u[
?|9$o/Q}
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 /L"&'~
P1l@K2r
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 H}c, P('
=1vVITwl
。 aw:0R=S,>
}t #Hq
分页支持类:
goT:\2
JZ=a 3)x"
java代码: H{T)?J~
dfq5P!'
Gu_Rf&:
package com.javaeye.common.util; 0IM#T=V
!kfnqe?|
import java.util.List; j{'@g[HW
]H|1quT
publicclass PaginationSupport { MY["
zv
5+O#5"v_
publicfinalstaticint PAGESIZE = 30; 4[&6yHJ^
wB(
igPi
privateint pageSize = PAGESIZE; :PaFC{O)*
O_PC/=m1@
privateList items; m"vV=6m|\
t(MlZ>H
privateint totalCount; 0,;FiOp
#Y*AG xk
privateint[] indexes = newint[0]; F'#e]/V1
:1>R~2
privateint startIndex = 0; 2h6F j&
zj;y`ENj
public PaginationSupport(List items, int F<w/@.&m
;SVF"Uo
totalCount){ i9M6%R1m}E
setPageSize(PAGESIZE); Ve8`5
setTotalCount(totalCount); [P{Xg:0
setItems(items); z[
;{p.W
setStartIndex(0); 4p~:(U[q
} (<.1o_Q-LU
2s6Hr;^w.1
public PaginationSupport(List items, int {_/6,22j(V
Ck.GN<#-^P
totalCount, int startIndex){ o#wF/ I
setPageSize(PAGESIZE); I$wP`gQh
setTotalCount(totalCount); }Gz"og*8
setItems(items); 5J&n<M0G1
setStartIndex(startIndex); uYMW5k_,>
} {hRAR8
Qg
_?..%
public PaginationSupport(List items, int 1^Zx-p3J
<$njU=YE&
totalCount, int pageSize, int startIndex){ ^?xXP=/
setPageSize(pageSize); Z?hBn`.
setTotalCount(totalCount); }RUC#aW1
setItems(items); 6]gs{zG
setStartIndex(startIndex); `u-VGd\
} D1O7S]j
Vq'&t<K#
publicList getItems(){ 28BiuxVW
return items; >k\*NW
} f3l >26
Ruk6+U
publicvoid setItems(List items){ SqTm/ t
this.items = items;
3nK'yC
} V`WfJ>{;Z
y~S[0]y>
publicint getPageSize(){ ypd
return pageSize; FJL9x,%6
} sfrh+o57
6y5arP*6e
publicvoid setPageSize(int pageSize){ {2:H`|x
this.pageSize = pageSize; m&A/IW,.
} |k+&weuY
-I8%
publicint getTotalCount(){ PUYo >eB)0
return totalCount; ln=zGX.e
} &GD7ldck
{h%.i Et%
publicvoid setTotalCount(int totalCount){ $oua]8!
if(totalCount > 0){ ci^-0l_O
this.totalCount = totalCount; 4GHIRH
C%[
int count = totalCount / 3P\I;xM
b]g.>$[nX
pageSize; @e0Q+ t
if(totalCount % pageSize > 0) $0W0+A$
count++; 'b^:"\t'Rh
indexes = newint[count]; Io"=X!k
for(int i = 0; i < count; i++){ UU
,)z
indexes = pageSize * $z,bA*j9
(wY%$kW4
i; gCm?nb)
} Xs`:XATb/
}else{ \qTn"1bQ
this.totalCount = 0; YHRI U Yd
} &'](T9kg=
} 2\5@_U^)h
_fyw
publicint[] getIndexes(){ 25~$qY_
return indexes; 9H)uTyuNi
}
7:p]~eM)
c,~44Z
publicvoid setIndexes(int[] indexes){ Uq+
_#{2(
this.indexes = indexes; m5x>._7le
} $c y:G
/pge 7P
publicint getStartIndex(){ ,/ig8~u'c
return startIndex; AeJM[fCMa
} f%}+.eD
jN<]yhqf
publicvoid setStartIndex(int startIndex){ slmxit
if(totalCount <= 0) .BUl$RW|
this.startIndex = 0; ?rK%;GTo
elseif(startIndex >= totalCount) s,29_z7
this.startIndex = indexes Q.]
)yqX6
Q:MsD.
[indexes.length - 1]; q7PRJX
elseif(startIndex < 0) Z{CL!
this.startIndex = 0; jI V? p
else{ .>nd@oU
this.startIndex = indexes $tKATL*
:cEe4a
[startIndex / pageSize]; &Egn`QU
} %7@H7^s}9
} m{5$4v,[
RQ'c~D)X
publicint getNextIndex(){ dB,#`tc=,
int nextIndex = getStartIndex() + vp|=q;Q%r
c]n03o
pageSize; (hV"z; rI
if(nextIndex >= totalCount) #~f+F0#%?
return getStartIndex(); 2Ee1mbZVw8
else U+RPn?Q
return nextIndex; &e)p6Egl
} 9}mp,egV
PmY:sJ{M
publicint getPreviousIndex(){ E9:hK
int previousIndex = getStartIndex() - 0X-2).nu
\O?B9_
pageSize; stG&(M
if(previousIndex < 0) Zs{R O
return0; Tz-cN
else Y_B 4s-
return previousIndex; iLgt_@g
} 4a |Fx
'9dtIW6E
} N9PM.nbd%
[-gKkOT8E
!U!E_D.O
2"'8x?.V
抽象业务类 MdjLAD)f+C
java代码: Os!22 O
*!/#39
H7=z%Y9y
/** .%<&W1
* Created on 2005-7-12 4~Pto
f@
*/ Ft rw3OxN
package com.javaeye.common.business; C941@I
7tpZE+OX
import java.io.Serializable; pdHb
import java.util.List; r97[!y1gt
3ky+qoe
import org.hibernate.Criteria; X&~Eo
import org.hibernate.HibernateException; p4EItRZS
import org.hibernate.Session; M\6`2q
import org.hibernate.criterion.DetachedCriteria; b
. j^US^
import org.hibernate.criterion.Projections; mlWIq]J
import =eoxT
N6[^62
org.springframework.orm.hibernate3.HibernateCallback; .rm7Sd4K
import Kx+Bc&X
LD~'^+W
org.springframework.orm.hibernate3.support.HibernateDaoS fEc_r:|\6
cZzZNGY^ts
upport; /xbZC{R
Z+W&C@Uw
import com.javaeye.common.util.PaginationSupport; Y]K]]Ehp
CEq]B:[IC
public abstract class AbstractManager extends g0OS<,:
,b(S=r
HibernateDaoSupport { vxT"BvN
DOIWhd5:
privateboolean cacheQueries = false; 3/=QZ8HA&-
jFTV\|C
privateString queryCacheRegion; 26VdRy{[
XL=R]IC<.
publicvoid setCacheQueries(boolean g VJ#LJ
`UK+[`E
cacheQueries){ Ux
T[
this.cacheQueries = cacheQueries; .e2A*9,
} a950M7
iQ{&&>V%
publicvoid setQueryCacheRegion(String 4G8nebv
ivX37,B\bS
queryCacheRegion){ W_,;eyo
this.queryCacheRegion = ,ANK3n\
}t51U0b%
queryCacheRegion; OW^2S_H5
} hJ[mf1je=
V}|v!h[O8
publicvoid save(finalObject entity){ ?
TT8|Os
getHibernateTemplate().save(entity); t0J5v ;
} LJ(n?/z%
6=,#9C9
publicvoid persist(finalObject entity){ CFJjh^
~=
getHibernateTemplate().save(entity); ^[,s_34V
} ~x4B/zW?
oCKM5AVWsv
publicvoid update(finalObject entity){ fQ36Hd?(5
getHibernateTemplate().update(entity); <@e+-$
} 4,U}Am1Q
/Fo/_=FE 2
publicvoid delete(finalObject entity){ C. Ja;RFq
getHibernateTemplate().delete(entity); TA0D{
} lgonR
GX@W"y
publicObject load(finalClass entity, W8,t l>(
J,1osG<6x
finalSerializable id){ },fo+vRM
return getHibernateTemplate().load u.kYp
G?ugMl}
(entity, id); &oeN#5Es8C
} j|&DP-@g/
B8UZ9I$n
publicObject get(finalClass entity, 27a*H1iQ
0Ox|^V
finalSerializable id){ fNqmTRu
return getHibernateTemplate().get 7SK3
%[nR|a<
(entity, id); zvGK6qCk
} wt}%2x} x
>Qm<-g
publicList findAll(finalClass entity){ N2tkCkl^x9
return getHibernateTemplate().find("from dm2CA0
3u4*ofjE5
" + entity.getName()); ~y)bYG!G
} $Pd|6
F:;!)H*
publicList findByNamedQuery(finalString w*:GM8=6
8jjFC9Cbn0
namedQuery){ *"5N>F[L
return getHibernateTemplate $,KP]~?
mLg{6qm(q
().findByNamedQuery(namedQuery); 2gwZb/'i
} B` *f(
p?V?nCv1O
publicList findByNamedQuery(finalString query, /^'Bgnez
MyH[v E^b
finalObject parameter){ G'O/JM
return getHibernateTemplate 5 o#<`_=J
{Z#e{~m#
().findByNamedQuery(query, parameter); >I4p9y(u
} |.(CIu~b
4bi NGl~
publicList findByNamedQuery(finalString query, i,#k}CNu
q]eFd6
finalObject[] parameters){ [0&'cu>
return getHibernateTemplate F!gNt<fZ
#v4LoNm
().findByNamedQuery(query, parameters); sTtX$&Qu
} +}^|dkc
W|25t)cJ8h
publicList find(finalString query){ ^sifEgG *d
return getHibernateTemplate().find ;8ET!&k*>E
?< cM^$lI>
(query); V uG?B{
} :K~rvv\L7
OJP5k/U$
publicList find(finalString query, finalObject <b d1
8K0X[-hs8
parameter){ pb^,Qvnp
return getHibernateTemplate().find ]*N:;J
'qL5$ zG
(query, parameter); !K3})& w
} 5@`F.F>"
38c?^
public PaginationSupport findPageByCriteria y=AsgJ
e}42/>}#D
(final DetachedCriteria detachedCriteria){ M{?.hq
return findPageByCriteria |h&<_9
"l@A[@R
(detachedCriteria, PaginationSupport.PAGESIZE, 0); 90/vJN
} S!;LF4VA
B< |VeU
public PaginationSupport findPageByCriteria 1 -ZJT
}zFf0.82
(final DetachedCriteria detachedCriteria, finalint Y[Q@WdE9
x\hWyY6J[
startIndex){ &{%MjKJ._
return findPageByCriteria v6s\Z\v)Q`
:qKF58W
(detachedCriteria, PaginationSupport.PAGESIZE, q!6|lZ B3
&]P"48NT
startIndex); nPcS3!7B#
} :{LAVMG&^
'LVn^TB_f&
public PaginationSupport findPageByCriteria &E
bI Op
0YzsA#yv
(final DetachedCriteria detachedCriteria, finalint ^Q0&.hL@
?Jt$a;
pageSize, ha*X6R
finalint startIndex){ ~>V-*NT8
return(PaginationSupport) $<B
+K
q|5Q?t:,r
getHibernateTemplate().execute(new HibernateCallback(){ 5|ic3
publicObject doInHibernate 8-7dokg>
zv //K_
(Session session)throws HibernateException { y
'Ol Q2U
Criteria criteria = "EoDQT"0
3VmI0gsm.>
detachedCriteria.getExecutableCriteria(session); dY} pN"
int totalCount = |6E
.M1
dUS ZNY
((Integer) criteria.setProjection(Projections.rowCount )QmGsU}?
h#i\iK&A
()).uniqueResult()).intValue(); >':5?\C+-
criteria.setProjection b1u}fp
GF
9UwLF`XM
(null); No)
m/17y
List items = WsR+Np@c
mN;+TN'?{
criteria.setFirstResult(startIndex).setMaxResults iq?l#}]
eNRs&^
(pageSize).list(); n~tqO!q
PaginationSupport ps = {<2>6 _z
Jf7frzw
new PaginationSupport(items, totalCount, pageSize, [*8Y'KX <
B'-I{~'/
startIndex); Wta]BX
return ps; ~-TOsRvxR
} 5IW8=$k~.)
}, true); *8bK')W
} .NJ|p=fy
%}q.cV
public List findAllByCriteria(final @6 /yu>%
>3 l=*|9
DetachedCriteria detachedCriteria){ %aU4,j^],o
return(List) getHibernateTemplate m9$ a"$c
{.st`n|xz
().execute(new HibernateCallback(){ H}Ucrv:
publicObject doInHibernate uWjN2#&,
0GZq`a7[
(Session session)throws HibernateException { DAdYg0efex
Criteria criteria = M;+IZr Wkl
4KXc~eF[M"
detachedCriteria.getExecutableCriteria(session); %-+j
return criteria.list(); GIT#<+"
} %_MEfuL
}, true); vJ"i.:Gf4
} whye)w
R(k}y,eh.`
public int getCountByCriteria(final P7:d ly[,q
=E(#YCx
DetachedCriteria detachedCriteria){ }aF
Integer count = (Integer) jk*tL8?i
wv?RO*E
getHibernateTemplate().execute(new HibernateCallback(){ BcQEG *N
publicObject doInHibernate h}Rx_d
s~^}F +n
(Session session)throws HibernateException { ~.^AL}zm_
Criteria criteria = )I`if(fG
Q&CElx?L
detachedCriteria.getExecutableCriteria(session); `'i( U7?
return a 7#J2 r
}#1/fok
criteria.setProjection(Projections.rowCount ~S*b
%{!R
l@
()).uniqueResult(); C&+6>L@
} Fv8f+)k)Z~
}, true); @MiH(.Dq
return count.intValue(); }4&/VvN
} P(,?#+]-
} w##^}nHOR
nirDMw[
A#rh@8h+
fE]XWA4U
Zd!U')5/
OcmRZ
用户在web层构造查询条件detachedCriteria,和可选的 *27*>W1
D3D}DaEYj
startIndex,调用业务bean的相应findByCriteria方法,返回一个 =wVJ%
&xXEnV
PaginationSupport的实例ps。 *nC(-(r:J`
zF`3gl.
ps.getItems()得到已分页好的结果集 rf.`h{!!
ps.getIndexes()得到分页索引的数组 8)L*AdDAW!
ps.getTotalCount()得到总结果数 WBr59@V
ps.getStartIndex()当前分页索引 : g6n,p_#
ps.getNextIndex()下一页索引 jZteooJG|
ps.getPreviousIndex()上一页索引 7B7&9<gc
w(9*7p p
",yc0 2<
`JB?c
q_V0+qH
PLX>-7@
,WDX(
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 nhT-Ido
v+G=E2Lhv
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 -F@L}|
j$Ab>}g]
一下代码重构了。 E{E0Z9t7&
t)f-mQz)
我把原本我的做法也提供出来供大家讨论吧: S<`I
Jpkv
e}hmS 1>H
首先,为了实现分页查询,我封装了一个Page类: 'n;OB4
java代码: )G~w[~
V5i*O3a~
A1"SLFY
/*Created on 2005-4-14*/ aNxAZMg
package org.flyware.util.page; eJ0?=u!x
:9|\Z|S(I
/** _oG&OJ@
* @author Joa bq>_qpr
* b2,!g }I
*/ g[H',)A)
publicclass Page { nKoiG*PI
|~!U4D\
/** imply if the page has previous page */ t] aea*B
privateboolean hasPrePage; qIIJ4n
8CbXMT
/** imply if the page has next page */ H+E$:)gN
privateboolean hasNextPage; \C,p
WW
3"N)xO-
/** the number of every page */ /FD5G7ES
privateint everyPage; ?W>qUrZ
qpIC{'A.
/** the total page number */ TaE~s
privateint totalPage; iOAbaPN
sEMQ
/** the number of current page */ p]T<HGJ P
privateint currentPage; +N`ua
9h&R]yz;
/** the begin index of the records by the current aJ Z"D8C
Gg Jf7ie4
query */ -m
*Sq
privateint beginIndex; Lk\P7w{
d.UQW
yLG
_g%TSumvq<
/** The default constructor */ B"yFS7Rrj
public Page(){ }}v9
`F
6AG`&'"
} 1#IlWEg
I/Jb!R ~
/** construct the page by everyPage |a1{ve[
* @param everyPage BTgG4F/)
* */ jTO),
v:w
public Page(int everyPage){ @,Gxk
this.everyPage = everyPage; hj'(*ND7z
} CI353-`
MZ+^-@X
/** The whole constructor */ ls@i".[
public Page(boolean hasPrePage, boolean hasNextPage, h8Yx#4
7d LuX
;AO#xv+#
int everyPage, int totalPage, !?c|XdjZ
int currentPage, int beginIndex){ 8Nu=^[qwQM
this.hasPrePage = hasPrePage; /xtq_*I1S
this.hasNextPage = hasNextPage; I:K"'R^
this.everyPage = everyPage; PB;eHy
this.totalPage = totalPage; 3k#~yaoI
this.currentPage = currentPage; ]vwW]O7
this.beginIndex = beginIndex; !*RqCS,
} VD_$$Gn*q
-py@DzK
/** FEVEp
* @return PDs@?nz,
* Returns the beginIndex. $Y69@s %f
*/ 1UPC e
publicint getBeginIndex(){ '>r7V
return beginIndex; EoK~S\dS
} '!/<P"5t
KQB3m"
/** 0c} }Q
* @param beginIndex yKO`rtP
* The beginIndex to set. +$g}4
*/ %CK^Si%+
publicvoid setBeginIndex(int beginIndex){ ``wSc0\
this.beginIndex = beginIndex; s"t$0cH9
} >=[(^l
}Y;K~J
/** '7XIhN9
* @return z`:lcF{V
* Returns the currentPage. (Jz1vEEV
*/ xlQBe-Wg
publicint getCurrentPage(){ 293M\5:
return currentPage; o!)3?
} On?p 9^9
8-2cRs
/** =Xo
=Qcr
* @param currentPage :Nz9xD$S5
* The currentPage to set. C.FI~Z
*/ ."9];)2rx
publicvoid setCurrentPage(int currentPage){ B)0i:"q
this.currentPage = currentPage; {{QELfH2
} Hv2De0W
j KoG7HH
/** +0OLc2
)w
* @return _H5o'>=
* Returns the everyPage. *s:(jDlv
*/ r-Pkfy(
publicint getEveryPage(){ UEguF&
return everyPage; ljb7oA3cP4
} lhqg$lb
[n:<8ho
/** }hhGu\
* @param everyPage Y\No4w ^|d
* The everyPage to set. k7T`bYv
*/ neLAEHV
publicvoid setEveryPage(int everyPage){ >U[j]V]
this.everyPage = everyPage; %^ !,t:d
} JU)dr4S?
FY#C.mL
/** 5yP\I+Fm
* @return )v.=jup[
* Returns the hasNextPage. MB]<Dyj,
*/ 8|\8O@
publicboolean getHasNextPage(){ a6uJYhS~
return hasNextPage; |>dI/_'
} fTK3,s1=
?`PvL!'
/** lE4HM$p
* @param hasNextPage _sTROd)Vh
* The hasNextPage to set. )8$=C#qC[
*/ ^G}47(
publicvoid setHasNextPage(boolean hasNextPage){ rR(X9i
this.hasNextPage = hasNextPage; =Jyu4j *}
} u)+8S/ )
~kEI4}O
/** uFinv2Z'
* @return |R/%D%_g
* Returns the hasPrePage. A;]}m8(*
*/ 1=d6NX)B
publicboolean getHasPrePage(){ \D*KGd]M0
return hasPrePage; 62ws/8d6f
} Yp^rR }N
k@k&}N0{
/** `T5W}p[6
* @param hasPrePage 6[ j.@[t
* The hasPrePage to set. ~E2KZm
*/ lww!-(<ww
publicvoid setHasPrePage(boolean hasPrePage){ Ng~FEl
this.hasPrePage = hasPrePage; H[U!%Z
} 3 cK I
0tT(W^ho g
/** :&V h?
* @return Returns the totalPage. ?kbiMs1;u
* c7x~{V8
*/ 4R1<nZ"e~
publicint getTotalPage(){ *Doa*wQ
return totalPage; LnH ?dy
} CYY=R'1:G{
$QLcH;+7t
/** 8
Hg+H=?
* @param totalPage 2fnkw/
* The totalPage to set. 0=2@
*/ 'h|DO/X~L
publicvoid setTotalPage(int totalPage){ P2#XKG
this.totalPage = totalPage; K8GP@yD]M
} nxnv,AZG
W{6|tx)
} Y5- F@(
$5aV:Z3P
z[L8$7L
!Prg_6
`
v$?+MNks
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 \`~Ly-
}v}P
.P
个PageUtil,负责对Page对象进行构造: R;&AijS8
java代码: 7&jTtKLj
K*LlW@
yerg=,$_i
/*Created on 2005-4-14*/ a|t$l=|DD
package org.flyware.util.page; =Y|VgV
r1 !@hT
import org.apache.commons.logging.Log; `yrB->|vG
import org.apache.commons.logging.LogFactory; xr4*{v
6t[+pL\b
/** 7)`nD<j5
* @author Joa
mHdA2
* i&bA2p3+d
*/ G|!Tj X7s
publicclass PageUtil { |"ls\ 7
Yvw(tj5_5
privatestaticfinal Log logger = LogFactory.getLog EE&K0<?T|:
GfoLae
(PageUtil.class); %*A0# F
.sha&
/** Y!-M_v /
* Use the origin page to create a new page 46_xyz3+
* @param page _.tVSVp
* @param totalRecords =_JjmTy;a
* @return mqD}BOif
*/ LM~[@_j
publicstatic Page createPage(Page page, int |W,&
Hl7
} gyj0
totalRecords){ z+0I#kM"1
return createPage(page.getEveryPage(), 3]}D`Qs6
%?0:vn
page.getCurrentPage(), totalRecords); @vC4[:"pD}
} w'Y7IlC
Xv ]W(f1
/** FtP0krO(
* the basic page utils not including exception XixL R
?uzRhC_)!
handler 7zXvnxYE
* @param everyPage )WNzWUfn=z
* @param currentPage }7|1
* @param totalRecords Yb|c\[ %
* @return page 2b}t,&bv?
*/ KrgFKRgGj
publicstatic Page createPage(int everyPage, int hZ?Rof
W <9T0sZ
currentPage, int totalRecords){ ,1~"eGl!
everyPage = getEveryPage(everyPage); (y=C_wvqZ
currentPage = getCurrentPage(currentPage); 3oF45`3FV
int beginIndex = getBeginIndex(everyPage, {f/~1G[M
k+# %DK
currentPage);
_C%3h5
int totalPage = getTotalPage(everyPage, TaZmRL
F~R;n_IJ
totalRecords); hgYZOwQ
boolean hasNextPage = hasNextPage(currentPage, 0fb2;&pUa
sEp"D+f
totalPage); R1adWBD>
boolean hasPrePage = hasPrePage(currentPage); + [iQLM?zo
132{#tG]
returnnew Page(hasPrePage, hasNextPage, }|0^EWL
everyPage, totalPage, ZQ4p(6a
currentPage, %aG5F}S2~
9vuyv*-}e
beginIndex); g/ T
} | k&Ck
\(?rQg@U
privatestaticint getEveryPage(int everyPage){ hci6P>h<ia
return everyPage == 0 ? 10 : everyPage; ? &o2st
} pA'4|ffwe
zqim R#u
privatestaticint getCurrentPage(int currentPage){ cvn@/qBq*t
return currentPage == 0 ? 1 : currentPage; "%`1]Fr
} dU&a{$ku[
<Th6r.#?
privatestaticint getBeginIndex(int everyPage, int yZ0-wI
g!g#]9j
currentPage){ jD$,.AVvz
return(currentPage - 1) * everyPage; "@e3EX7h
} =_.l8IYX$%
dN$0OS`s[
privatestaticint getTotalPage(int everyPage, int e>} s;H,
J{.{f
totalRecords){ 0.`/X66;V
int totalPage = 0; Z;ht
Q- cFtu-w
if(totalRecords % everyPage == 0) m|SUV
totalPage = totalRecords / everyPage; Rvqq.I8aC
else RD!&LFz/}
totalPage = totalRecords / everyPage + 1 ; &jS>UsGh
z Xg3[orF
return totalPage; xT3BHnQ(
} zU5v /'h>d
ISYXH9V
privatestaticboolean hasPrePage(int currentPage){
(ZS}G8
return currentPage == 1 ? false : true; ]FJjgu<