Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 ,;3bPjey
2TFb!?/RQ
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 F$L2bgQR?'
1NHiW
v
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 I5nxY)v
j,DF' h
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 <WXGDCj
NCW<~
。 q=I8W}Zi
l#%qF Db
分页支持类: #'DrgZ)W
a0wSXd
java代码: (p19"p
oo+i3af&7
PK C}!>2
package com.javaeye.common.util; WqX$;'}h
UL{+mp
import java.util.List; 0+-"9pED>E
1c5+XCr
publicclass PaginationSupport { ,/fB~On-
YC!IIE_
publicfinalstaticint PAGESIZE = 30; .<m${yU{3
_GhP{C$
privateint pageSize = PAGESIZE; |IcA8[
<{ER#}b:O
privateList items; PO*;V<^
k.."_4
privateint totalCount; _i3?;Fds
M]Kxg;
privateint[] indexes = newint[0]; :P2{^0$
:VkuK@Th`
privateint startIndex = 0; c
-sc*.&
8+*
1s7{
public PaginationSupport(List items, int v}cTS@0
?\Bm>p%+
totalCount){ p*NKM}
]I
setPageSize(PAGESIZE); c-`'`L^J
setTotalCount(totalCount); }1xD*[W
setItems(items); Cs!z3QU
setStartIndex(0); 009[`Z
} XRl!~Y|
r,43 gg
public PaginationSupport(List items, int 0hNgr'
T'ko =k
totalCount, int startIndex){ /` ;rlH*
setPageSize(PAGESIZE); ;L*Ku'6Mt
setTotalCount(totalCount); ]>9[}'u
setItems(items); .4[\%r\i
setStartIndex(startIndex); _J,lF-,
} '?Jz8iu-
Z|#G+$"QV
public PaginationSupport(List items, int MJ\^i4
euMJ c
totalCount, int pageSize, int startIndex){ #Dz. 58A
setPageSize(pageSize); r"_U-w
setTotalCount(totalCount); ^ g'P
H{68
setItems(items); 5i0vli/L
setStartIndex(startIndex); 7DZZdH$Fm
} YHp]O+c
XLgp.w;
publicList getItems(){ ]lqe,>
return items; (v,g=BS,
} ;hgRMkmz4<
9cIKi#Bl
publicvoid setItems(List items){ p!o?2Lbiw
this.items = items; F(;=^w
} Leu93f2
&cpqn2Z
publicint getPageSize(){ L^FQ|?*
return pageSize; z%q)}$O
} a5k![sw\
p
2>\
publicvoid setPageSize(int pageSize){ l!*!)qCB(S
this.pageSize = pageSize; 9Ro7xSeD
} s~NJy'Y
?mp}_x#=
publicint getTotalCount(){ :|HCUZ*H(T
return totalCount; ==Ah& ){4^
} <~bvfA=
;%Zu[G`C
publicvoid setTotalCount(int totalCount){ jmBsPSGIC
if(totalCount > 0){ ,$+ P
this.totalCount = totalCount;
@hF$qevX
int count = totalCount / 6n?0MMtR
]<BT+6L
pageSize; 8x`EUJ
if(totalCount % pageSize > 0) $xqX[ocor
count++; Aa`R40 yl
indexes = newint[count]; M:*)l(
for(int i = 0; i < count; i++){ u.@B-Pf[Eo
indexes = pageSize * ROr|n]aJj
~f6Q
i; O +u?Y
} O~OM.:al&
}else{ AsfmH-4)
this.totalCount = 0; ._[uSBR'
} Zs|m_O G
} STL+tLJ
GUps\:ss
publicint[] getIndexes(){ z7s}-w,
return indexes; veAdk9
} E h+m|A
[{q])P;
publicvoid setIndexes(int[] indexes){ zi_0*znw
this.indexes = indexes; P
r2WF~NuO
} Ou] !@s
Q"s]<MtdS
publicint getStartIndex(){ $}t;c62
return startIndex; YS bS.tq
} A~@x8
pG^>y0
publicvoid setStartIndex(int startIndex){ v=~+o[
if(totalCount <= 0) %$&_!
this.startIndex = 0; WS.lDMYE7
elseif(startIndex >= totalCount) QKI g5I-
this.startIndex = indexes MmQk@~
\gGTkH
[indexes.length - 1]; V
X.9mt
elseif(startIndex < 0) 6J<R;g23R]
this.startIndex = 0; *o=[p2d"X
else{ &9EcgazV
this.startIndex = indexes 2-%9k)KH
wW,
n~W
[startIndex / pageSize]; tfdb9#&?
} 48)D%867.;
} gLwrYG7@
.1:B\R((
publicint getNextIndex(){ e3k58
int nextIndex = getStartIndex() + r8Z.}<j
UmL Boy&*
pageSize; eWr2UXv$
if(nextIndex >= totalCount) :j`4nXm
return getStartIndex(); X`A+/{ H
else 7;a
return nextIndex; Ae*
6&R4
} {Fvl7Sh
!>:]k?$b
publicint getPreviousIndex(){ g*;zVi
int previousIndex = getStartIndex() - q4SEvP}fLx
LaYd7Oyf]
pageSize; ^|(VI0KO
if(previousIndex < 0) z:;yx
return0; t]hfq~Ft
else [ZL<Q
return previousIndex; Y+DVwz$
} oml^f~pm
#'97mg
} H`4KhdqR
riQ0'-p
m$VCCDv
GO3KKuQ=
抽象业务类 qS?^(Vt|R
java代码: !
u9LZ
t4UL|fI
V6&6I
/** J;N\q
* Created on 2005-7-12 ~!P&LZ
*/ |#sY(1
package com.javaeye.common.business; JvF0s}#4
= Atyy
import java.io.Serializable; deOk>v&U
import java.util.List; 3F$N@K~s
\F14]`i
import org.hibernate.Criteria; -d[Gy-
J
import org.hibernate.HibernateException; 13A~."b
import org.hibernate.Session; jd.w7.8
import org.hibernate.criterion.DetachedCriteria; X2`n&JE
import org.hibernate.criterion.Projections; oK3PA
import WO*dO9O
Ap> H-/C
org.springframework.orm.hibernate3.HibernateCallback; l6N"{iXU
import SP;1XXlL
aWY#gI{
org.springframework.orm.hibernate3.support.HibernateDaoS k{ulu
]f6,4[
upport; [*g'Y;W
_e "
import com.javaeye.common.util.PaginationSupport; '26
,.1
xmejoOF
public abstract class AbstractManager extends CUx-k|\
.ZupsS9l
HibernateDaoSupport { Hq|{Nt%Q
4veXg/l
privateboolean cacheQueries = false; L0*f(H
++BQ==@
privateString queryCacheRegion; 2p~G][
@2sr/gX^
publicvoid setCacheQueries(boolean 71Y3.1+
Pu(kCH{
cacheQueries){ ;Q<2Y#
this.cacheQueries = cacheQueries; v!#koqd1y.
} _$yS4= .
@v/
8}n
publicvoid setQueryCacheRegion(String |$[.X3i
e\}'i-
queryCacheRegion){ 8peK[sz
this.queryCacheRegion = 9O\yIL
/d>Jkv
queryCacheRegion; \*Z:w3;r
} 5k;}I|rg %
NYeL1h)l
publicvoid save(finalObject entity){ dvLL~VP
getHibernateTemplate().save(entity); =00sB
} _Nf%x1m5s
=(Y+u
publicvoid persist(finalObject entity){ C|RC9b
getHibernateTemplate().save(entity); |N|[E5Cn
} NW`Mc&
bQHJ}aCi
publicvoid update(finalObject entity){ =<Ss&p>
getHibernateTemplate().update(entity); ,vB nr_D#
} :M.]- +(
vV>=Uvm
publicvoid delete(finalObject entity){ I=;=;-
getHibernateTemplate().delete(entity); ufN`=IJ%
} x5k6"S"1,
b<BkI""b
publicObject load(finalClass entity, GD4+f|1.*
LAuaowE\v
finalSerializable id){ %Lom#:L'
return getHibernateTemplate().load (R!`Z%
,#hNHFa'JH
(entity, id); )!5"\eys
} HG3iK
D 1(9/;9
publicObject get(finalClass entity, HFX,EE
_+<AxE9\
finalSerializable id){ G#3$sz
return getHibernateTemplate().get q)N^
vAtR\Vh
(entity, id); Er|j\(jM
} Q@rlqWgU
~
eY_BECJ+OO
publicList findAll(finalClass entity){ /EwNMU*6
return getHibernateTemplate().find("from #yOeL3|b'
/U="~{*-R
" + entity.getName()); e'~<uN>
} W,.Exh
c#a>> V
publicList findByNamedQuery(finalString (]$&.gE.F
+u3vKzD
namedQuery){ pz]KUQ
return getHibernateTemplate <q=]n%nX
v>5TTL~?
().findByNamedQuery(namedQuery); ~zFwSF
} c1 1?Kq
\7Fp@ .S3
publicList findByNamedQuery(finalString query, MpJ]1
"F?p Y@4
finalObject parameter){ |al'_s}I
return getHibernateTemplate zS `>65}e
> (W\Eh{J
().findByNamedQuery(query, parameter); E :UJ"6
} bK|nxL
uP1]EA
publicList findByNamedQuery(finalString query, `)M&^Z=D
]E1|^[y
finalObject[] parameters){ -uB*E1|Q
return getHibernateTemplate =j8g6# 'u
4TcW%
().findByNamedQuery(query, parameters); p%5(Qqmlk
} Q.SqOHeJ
UbP$WIrq
publicList find(finalString query){ ;e Mb$px
return getHibernateTemplate().find
WDh*8!)
DK<}q1xi
(query); rR(\fX!dg
} !
;R}=
G.qjw]Llf
publicList find(finalString query, finalObject J:\O .F#Fi
aK8X,1g%)
parameter){ I} \`l+
return getHibernateTemplate().find cLIeo{H
_
Uv3glK
(query, parameter); ^NrC8,p
} z[0t%]7l
($[@'?Z1
public PaginationSupport findPageByCriteria _:G>bU/^
Yz>8 Nn '_
(final DetachedCriteria detachedCriteria){ ZU5; w
return findPageByCriteria 8[IR;gZf
gO bP
(detachedCriteria, PaginationSupport.PAGESIZE, 0); )Nl xW5
} WU6F-{M"?
TWU1@5?Ct
public PaginationSupport findPageByCriteria Kj+TPqXb
oi%IHX(`
(final DetachedCriteria detachedCriteria, finalint ]GzfU'fOn|
#wF6Wx iG
startIndex){ d4LH`@SUZ-
return findPageByCriteria _p%@x:\
t#7owY$^
(detachedCriteria, PaginationSupport.PAGESIZE, ~\Udl
mnM$#%q;%
startIndex); ];Y tw6A
} V.w!]{xm
|L6 +e*
public PaginationSupport findPageByCriteria VpB+|%@p
*m&(h@l
(final DetachedCriteria detachedCriteria, finalint jk5C2dy
\5F
{MBx !
pageSize, m[A$Sp_"-h
finalint startIndex){ ,sn
9&E
return(PaginationSupport) ZV`o:Gd
I_na^sh*
getHibernateTemplate().execute(new HibernateCallback(){ ^/7Y3n!|3
publicObject doInHibernate %&iWc_"
0V'XE1h
(Session session)throws HibernateException { 9<"l!noy
Criteria criteria = ]Waa7)}DM
hJ(S]1B~G
detachedCriteria.getExecutableCriteria(session); M1XzA
`*
int totalCount = + $/mh
eX o@3/
((Integer) criteria.setProjection(Projections.rowCount ksQw|>K
SoB6F9
()).uniqueResult()).intValue(); 34qfP{9!N
criteria.setProjection !p3vnOX6
fUB+9G(Bx
(null); Kk/cI6`W
List items = 't3nh
<s5s<q2
criteria.setFirstResult(startIndex).setMaxResults h\*I*I8C
}z_7?dn/
(pageSize).list(); KOD%>+vG$
PaginationSupport ps = Wq*W+7=.
#mc6;TRZO
new PaginationSupport(items, totalCount, pageSize, qZX\riR
vFsl]|<;8
startIndex); ^-K~y
return ps; t/a
} t<znz6
}, true); }E\u2]
} TuzH'F
;V4f6[<]'z
public List findAllByCriteria(final s6_[H
E=l^&[dIl
DetachedCriteria detachedCriteria){ ~tqDh(
return(List) getHibernateTemplate 'h;x>r
o*s3"Ib
().execute(new HibernateCallback(){ qr?RU .W
publicObject doInHibernate 8#15*'Y
_E
xd:
(Session session)throws HibernateException { CI@qT}Y_
Criteria criteria = ?.,2EC=+
w(nQ:;oC
detachedCriteria.getExecutableCriteria(session); Y !AQ7F
return criteria.list(); Yx<wYzD
} [2nPr^
}, true); (J`EC
} Eo_;Nc
@'FO M
public int getCountByCriteria(final /7Ft1f
r r(UE
DetachedCriteria detachedCriteria){ JAI ;7
Integer count = (Integer) q%k _C0
_eMY?
getHibernateTemplate().execute(new HibernateCallback(){ M}`G}*
publicObject doInHibernate b "5WsJ:'#
`Qo}4nuRs
(Session session)throws HibernateException { 4AuJ1Z
Criteria criteria = <k-hRs2d
$|}PL[aA#
detachedCriteria.getExecutableCriteria(session); }B2qtb3
return |BA<> WE
>y
iE}
criteria.setProjection(Projections.rowCount kB;!EuL
of?0 y-LT%
()).uniqueResult(); FY <77i
} xi"Ug41)
}, true); =idZvD
return count.intValue(); "6o5x&H
} C/A~r
} #nJ&`woZt
Ixv/xI
-gb'DN1BG
f7j9'k
bGa"r
pn4~?Aua0/
用户在web层构造查询条件detachedCriteria,和可选的 /&G )IY]g
Fx' E"d
startIndex,调用业务bean的相应findByCriteria方法,返回一个 &Ch~$Wb^
c9R|0Yn^J
PaginationSupport的实例ps。 )>rHM6-W
{Qj7?}xW
ps.getItems()得到已分页好的结果集 =E'
.T0v
ps.getIndexes()得到分页索引的数组 hS+R/7
ps.getTotalCount()得到总结果数 {Aq:Kh`&
ps.getStartIndex()当前分页索引 dE|luN~
ps.getNextIndex()下一页索引 JM Ikr9/$
ps.getPreviousIndex()上一页索引 S*?x|&a
RaLc}F)9
6T{SRN{
^Ts8nOGMh
J9yB'yE8
?u_O(eg
#Vh$u%q3
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 ~F=,)GE
Z|qUVD5Ic
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 cp<jwcc!
bdkxCt
一下代码重构了。 1PjqXgN5p
Blnc y
我把原本我的做法也提供出来供大家讨论吧: uQtwh08i
mY,t]#^m7
首先,为了实现分页查询,我封装了一个Page类: #~`]eM5`J
java代码: keL!;q|r-)
?tFsSU
.q9wyVi7GI
/*Created on 2005-4-14*/ eFdN"8EW
package org.flyware.util.page; WHvU|rJ
\Yd
0oe82
/** p) ea1j>N
* @author Joa TkSeDP
* (k&r^V/=
*/ 7T}r]C.
publicclass Page { o!ycVY$yW
)NCkq~M
/** imply if the page has previous page */ 'ai!6[|SD
privateboolean hasPrePage; DX%D8atrr
~7Jj\@68
/** imply if the page has next page */ #Ez+1
privateboolean hasNextPage; cWNWgdk,`V
Tx\g5rk
/** the number of every page */ ,7nA:0P
privateint everyPage; #Do#e
{=+
rYwUD7ip
/** the total page number */ 5D%gDw+"
privateint totalPage; zaoC
Wx-vWWx*Q
/** the number of current page */ eGh7 ,wngH
privateint currentPage; d65t"U
hpOUz%
/** the begin index of the records by the current "[BDa}Il
,3E9H&@j
query */ Du."O]syD
privateint beginIndex; !wZ9P
W:z!fh-
#8[iqvE
/** The default constructor */ J,=:
]t
public Page(){ bD;c>5t
OlF5~VAbfb
} v9R"dc]0h
[#-!&>
/** construct the page by everyPage =j{r95)|u
* @param everyPage b&1-tYV
* */ <m3or
public Page(int everyPage){ xRU ~hQ
this.everyPage = everyPage; 4%L-3Ij
} ^HasT4M+x
Ee?+IZ H7|
/** The whole constructor */ 'fkaeFzOl
public Page(boolean hasPrePage, boolean hasNextPage, ie%_-
lSk<euCYs
czv )D\*
int everyPage, int totalPage, 3JR1If
int currentPage, int beginIndex){ Lc:DJA
this.hasPrePage = hasPrePage; 9x40
this.hasNextPage = hasNextPage; c@1q8,
this.everyPage = everyPage; @ dF]X
this.totalPage = totalPage; g2'Q)w
this.currentPage = currentPage; t[-0/-4
this.beginIndex = beginIndex; HAr_z@#E
} }.R].4gT
(&a<6k
/** Y?>us
* @return mC}!;`$8p
* Returns the beginIndex. >7^+ag~&
*/ r!7e:p JLO
publicint getBeginIndex(){ /NDuAjp[@
return beginIndex; [Ifhh2
} 8xEOR!\!`k
;y{VdT
/** :9Vd=M6,
* @param beginIndex +e6c4Tw/
* The beginIndex to set. 2!4.L&Ki
*/ '#b7Z?83C
publicvoid setBeginIndex(int beginIndex){ _7M! b9oA
this.beginIndex = beginIndex; ToB^/
n[
} 5@{+V!o,
Mn=5yU
/** +.b@rU6H
* @return )5Bkm{v3
* Returns the currentPage. a} w%k
*/ khW9n*
publicint getCurrentPage(){ X0.-q%5
return currentPage; P6E=*^^m(
} +L$,jZqS
Kx;DmwX-
/** OJ'x>kE
* @param currentPage oe5.tkc
* The currentPage to set. h1 D#,
*/ (BA2
publicvoid setCurrentPage(int currentPage){ ;|Z;YK@20
this.currentPage = currentPage; Q&9%XF
uM
} >Lo!8Hen
dWI.t1`i
/** Z{w{bf1&A
* @return "k${5wk#Fl
* Returns the everyPage. [?$|
*/ Gkr^uXNg#
publicint getEveryPage(){ ?"aj&,q+
return everyPage; iZy`5
} L8~nx}UP5
O&:0mpRZ
/** VhAZncw
* @param everyPage P~+?:buqc
* The everyPage to set. _uO#0
)l
*/ |@-%x.y
publicvoid setEveryPage(int everyPage){ i~IQlyGr.
this.everyPage = everyPage; B9Dh^9?L
} Qw$"W/&X
r $du-U
/** FBGHVV
w!
* @return !7g
E
* Returns the hasNextPage. a*pZcv<
*/ %acy%Sy
publicboolean getHasNextPage(){ B=;pyhc
return hasNextPage; =oF6|\]{;
} O^]I>A#d
@HfWAFT
/** RT45@
* @param hasNextPage O8+[)+6^
* The hasNextPage to set. 4JHQ^i-aY
*/ Or9@ X=C
publicvoid setHasNextPage(boolean hasNextPage){ ~EU[?
this.hasNextPage = hasNextPage; f$E66yG
} 4Pljyq:
<(JsB'TK
/** n/"T7Y\2
* @return 6Upg\(
* Returns the hasPrePage. wE75HE`gW
*/ /s%I(iP4
publicboolean getHasPrePage(){ 1>*]jj}
return hasPrePage; >5Zpx8W
} ^gFjm~2I
7F-b/AdVq
/** xLZQ\2q
* @param hasPrePage lxK_+fj
q
* The hasPrePage to set. yvxC/Jo4
*/ 6QRfju'
publicvoid setHasPrePage(boolean hasPrePage){ =3=KoH/'
this.hasPrePage = hasPrePage; zJMKgw,i*
} l\^q7cXG
);h\0w>3
/** Z"gllpDr$
* @return Returns the totalPage. oQDOwM,
* JLAg-j2
*/ #{0DpSzE5
publicint getTotalPage(){ 81_3{OrE<
return totalPage; D,eJR(5I
} 7atYWz~yG
.;tO;j|6
/** yj$S?B Ee
* @param totalPage v%<_Mh
* The totalPage to set. P&aH6*p1
*/ >*} qGk
publicvoid setTotalPage(int totalPage){ 3i(k6)H$4
this.totalPage = totalPage; L1Q QU
} ]@J}f}Mjo
@`.u"@
} !BEOeq@2.
U>;itHW/
?<frU ,{
T *t$
-R'p^cMA
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 7IJb$af:;
3r em"M
个PageUtil,负责对Page对象进行构造: 29ft!R>[
java代码: Xy*X4JJh^
\ b9,>
na']{a1K
/*Created on 2005-4-14*/ ;(0:6P8I
package org.flyware.util.page; `A
<yDy
!T,7
import org.apache.commons.logging.Log; TjI NxP-O
import org.apache.commons.logging.LogFactory; e+R.0E
xdo{4XY^*W
/** ^y6Pkb
P
* @author Joa E2*"~gL^,
* xYu~}kMu
*/ @?]-5 ~3;
publicclass PageUtil { \S7OC
%yw*!A1
privatestaticfinal Log logger = LogFactory.getLog Sw1]]-Es
N~>?w#?J
(PageUtil.class); CJKH"'u3^
Z `\7B e
/** ^}1RDdQ"U
* Use the origin page to create a new page ^/n[5@6H
* @param page S,(@Q~
* @param totalRecords iKabo,~
* @return Y(SI`Xo[
*/ qk,cp},2K
publicstatic Page createPage(Page page, int qfYb\b
<Z8] W1)
totalRecords){ hTG
d Uw]
return createPage(page.getEveryPage(), 8]?1gDS|9O
W=EO=}l#
page.getCurrentPage(), totalRecords); UiZ61lw
} Gm2rjpZeq
UdI>x 4bI
/** 1M;)$m:
* the basic page utils not including exception .sG,TLE[<
rFy9K4D
handler Na~_=3+a
* @param everyPage wO!hVm,Ta
* @param currentPage Y!7P>?)`,X
* @param totalRecords k(qQvn
* @return page Wq9s[)F"Z
*/ ?^ErrlI_
publicstatic Page createPage(int everyPage, int #P9VX5Tg
!F<?h e<U
currentPage, int totalRecords){ Awh"SUOh0
everyPage = getEveryPage(everyPage); =h_gj >
currentPage = getCurrentPage(currentPage); %9D@W*Z
int beginIndex = getBeginIndex(everyPage, /3TorB~Y
I@S<D"af
currentPage); xRY5[=97
int totalPage = getTotalPage(everyPage, \QMSka>
?@#}%<yEq
totalRecords); Ys_YjlMIbl
boolean hasNextPage = hasNextPage(currentPage, Qx,G3m[}
-mkync3
totalPage); o7T|w~F~R
boolean hasPrePage = hasPrePage(currentPage); 1I+5
:> q?s
returnnew Page(hasPrePage, hasNextPage, Y>#c2@^i<
everyPage, totalPage, j d81E
currentPage, .-|O "H$
5?fk;Q9+\
beginIndex); >@L
HJ61C
} a2rv4d=
#`fT%'T!
privatestaticint getEveryPage(int everyPage){ |@g1|OWd|
return everyPage == 0 ? 10 : everyPage; 5->PDp
} OX`n`+^D
jF;4
8g@^
privatestaticint getCurrentPage(int currentPage){ OWjZ)f/
return currentPage == 0 ? 1 : currentPage; 8
KkpXaz
} Vx*q'~4y!|
,pASjFWi
privatestaticint getBeginIndex(int everyPage, int piG1&*
$~YuS_sYg
currentPage){ c~'kW`sNV
return(currentPage - 1) * everyPage; @iRVY|t/
} 1}uDgz^
z )pV$
privatestaticint getTotalPage(int everyPage, int I7~|!d6
=z3jFaZ
totalRecords){ op-#Ig$#
int totalPage = 0; \+uqP:Ty
biG9?
if(totalRecords % everyPage == 0) yn#h$o<
totalPage = totalRecords / everyPage; A%PPG+IfA
else l17ZNDzLU
totalPage = totalRecords / everyPage + 1 ; UH.cn|R
bevT`D
return totalPage; ~ tLR
} _'7/99]4g}
*02( J
privatestaticboolean hasPrePage(int currentPage){ W*<]`U_.
return currentPage == 1 ? false : true; <C$<