Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 [mphiH/
=jIB5".
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 3a #2 }
`oP :F[B
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 V8ka*VJ(B
.w3.zZ0[
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 U8L%=/N>B
f.acH]p
。 |Fz/9+I
NXsDn&&O
分页支持类: Br.$:g#
$j*%}x~[
java代码: 89T xd9X
O@r%G0Jge
x? 3U3\W
package com.javaeye.common.util; p\OUx Am
8enlF\I8g
import java.util.List; heJ I5t,
]vRte!QJ;
publicclass PaginationSupport { K|nh`r
_<pSCR0
publicfinalstaticint PAGESIZE = 30; h`n,:Y^++P
|kJ'FZZd
privateint pageSize = PAGESIZE; gSQq
'fO[f}oa_.
privateList items; DXu915
9TRS#iVL+*
privateint totalCount; @\0U`*]^)
\'Oi0qo>
privateint[] indexes = newint[0]; m
"'
tE3#Uq
privateint startIndex = 0; [4L[.N@
~t7?5b?*\
public PaginationSupport(List items, int )
=-$>75Z
Hhx"47:
totalCount){ @9_H4V
setPageSize(PAGESIZE); J'c]':U
setTotalCount(totalCount); ZDEz&{3U;
setItems(items); xR;>n[6
setStartIndex(0); !5I;3EN
} SQ%B"1&$D
KZoIjK]
public PaginationSupport(List items, int q6DuLFatc*
o2M+=O@
totalCount, int startIndex){ u^.7zL+
setPageSize(PAGESIZE); M )4-eo
setTotalCount(totalCount); U-~cVk+LI
setItems(items); fA"N5qQI(
setStartIndex(startIndex); n
N.6?a
} ILi{5L
}j<:hDQP
public PaginationSupport(List items, int \Ps}1)wT
UrtA]pc3L
totalCount, int pageSize, int startIndex){ %N5gQXg
setPageSize(pageSize); f_A'.oq+
setTotalCount(totalCount); Mttt]]
setItems(items); m? 3!
setStartIndex(startIndex); zT$-%
} <Y%km[Mh
wW2b?b{*Z
publicList getItems(){ t&scvXh
return items; Zo$,{rl
} =iJfz
+xoh=m
publicvoid setItems(List items){ K"Vo'9R[_
this.items = items; {qxFRi#\k
} iCd$gwA>F
VF#2I%R*
publicint getPageSize(){ x=-dv8N?
return pageSize; FPAy.cljJ
} pO]{Y?X:
MU_8bK9m
publicvoid setPageSize(int pageSize){ nV`n=x
this.pageSize = pageSize; T''PzY!Qf
} GSlvT:k
ng,64(wOY
publicint getTotalCount(){ ~>2DA$Ec
return totalCount; j&6O1
} Mw{0A\6
vP k\b 3E
publicvoid setTotalCount(int totalCount){ m.:2G
if(totalCount > 0){ -@*[
this.totalCount = totalCount; %K9pnq/T^
int count = totalCount / R1,.H92
AQ}(v,DOb
pageSize; R\i8O^[
if(totalCount % pageSize > 0) W^(:\IvV
count++; gteG*p i
indexes = newint[count]; i^<P@ |q
for(int i = 0; i < count; i++){ ;dC>$_P?
indexes = pageSize * D./!/>@f
Z~X \Z.
i; ,Z3 (`ftC
} Kivr)cIG
}else{ v@xbur\L
this.totalCount = 0; a,$v; s/
} QaVxP1V#U
} )Bz2-|\
62-,!N 1-
publicint[] getIndexes(){ !
.q,m>?+
return indexes; ejFGeR
} E \p Qh
g$^:2MT"aQ
publicvoid setIndexes(int[] indexes){ \`kH2`
this.indexes = indexes; }q$6^y
} XJ$mRh0`K
e7O9q8b
publicint getStartIndex(){ wI0NotC
return startIndex; ^i"~6QYE
} uGoySt&;(
+VSq [P
publicvoid setStartIndex(int startIndex){ sxK|0i}6
if(totalCount <= 0) 13JZ\`ceb
this.startIndex = 0; W{El^')F
elseif(startIndex >= totalCount) Z&Qz"V>$
this.startIndex = indexes B2kKEMdGg
}EMds3<
[indexes.length - 1]; Yl$R$u)
elseif(startIndex < 0) t| cL!
this.startIndex = 0; Hxr)`i46
else{ JmP[ 9"
this.startIndex = indexes 5LX'fL7zU
&^7^7:Y=?
[startIndex / pageSize]; f{HjM?
Mb3
} :>q*#vlb
} u3k{s
rYKGBo8"
publicint getNextIndex(){ }x~1w:zHd
int nextIndex = getStartIndex() + qlU"v)Mx
m>:zwz< ;
pageSize; f(*ygI
if(nextIndex >= totalCount) L|`(u
return getStartIndex(); C$x
r)_
else J1\H^gyW)
return nextIndex; `zP{E T_Y
} f\vy5''
V4CL%i
publicint getPreviousIndex(){ eh6\y79g
int previousIndex = getStartIndex() - FhFP M)[
/@O$jlX5I
pageSize; v;ZIqn"
if(previousIndex < 0) Vb++K0CK
return0; 1
k\~%
else L#~z#
return previousIndex; &_o.:SL|
} oD8X]R,
H
Q1
5h \!u
} %NH{%K,
v*lj>)L
RQ*oTsq
^ fqco9^;
抽象业务类 #\T5r*W
java代码: HxnWM\ p
tPz!C&.=
[9H986=
/** YsA.,
* Created on 2005-7-12 +\s&v!
*/ x&d:V
package com.javaeye.common.business; E5. @=U,c
RA3!k&8?#
import java.io.Serializable; B4RP~^
import java.util.List; +'ADN!(B_
;NPbEPL[5
import org.hibernate.Criteria; )+dd
import org.hibernate.HibernateException; #,jw! HO]
import org.hibernate.Session; O
<#H5/Tq
import org.hibernate.criterion.DetachedCriteria; V6a+VfH
import org.hibernate.criterion.Projections; ;-"'sEu}
import UC*\3:>'n
I%'6IpR"d
org.springframework.orm.hibernate3.HibernateCallback; oeA}b-Ct0
import $/|2d4O:{
SUaXm#9
org.springframework.orm.hibernate3.support.HibernateDaoS p;P
cD
sA:k8aj
upport; U%4s@{7
vcz?;lg
import com.javaeye.common.util.PaginationSupport; %"=qdBuk
f~Ve7
public abstract class AbstractManager extends 4&}dA^F
b3^d!#KVM
HibernateDaoSupport { CZ|h` ";P2
?:c:D5N
privateboolean cacheQueries = false; *'\xlsp#
D]*<J"/]d
privateString queryCacheRegion; g"|/^G_6S
bVW2Tjc:
publicvoid setCacheQueries(boolean =q"o%dc`R
]`T*}$|
cacheQueries){
v7#`b}'W
this.cacheQueries = cacheQueries; N*6lyFcg
} OqlP_^Zz7p
!v?WyGbUg
publicvoid setQueryCacheRegion(String mY0FewwTy
?a{es!
queryCacheRegion){ mj|TWDcj+
this.queryCacheRegion = *jrQ-'<T
vQsI^p
queryCacheRegion; Q'R*a(pm
} *sYvV,
QvvH/u
publicvoid save(finalObject entity){ xt=ELzu$
getHibernateTemplate().save(entity); C~q&
} Rw]lW;EN<
1qN+AT
publicvoid persist(finalObject entity){ MwO`DrV
getHibernateTemplate().save(entity); iVAAGZ>am
} Uk<2XGj
;)ji3 M
publicvoid update(finalObject entity){ qJ%AbdOI8
getHibernateTemplate().update(entity); u3])_oj=
} SioP`*,}
U^Ulj/%6
publicvoid delete(finalObject entity){ >8=rD
getHibernateTemplate().delete(entity); q&d5V~q
} 3}gf%U]L
\Rz-*zr&
publicObject load(finalClass entity, JH`oa1b
2YhtD A
finalSerializable id){ 29kR7[k
return getHibernateTemplate().load 0.lOSAq
)9s
6(Iu
(entity, id); |Wz`#<t
} f,0,:)
/ &#b*46
publicObject get(finalClass entity, ~%d* #Yxq
C)R#Om
finalSerializable id){ CA5q(ID_
return getHibernateTemplate().get .g52p+Z#
'Z82+uU%
(entity, id); _>4Qh#6K
} zelM}/d
&09g0K66
publicList findAll(finalClass entity){ WeE1 \
return getHibernateTemplate().find("from /6yH ,{(a
SPo}!&p$~
" + entity.getName()); =x5k5NIF
} cC7&]2X +f
q^^&nz<A
publicList findByNamedQuery(finalString `~+[pY1r
2'5u}G9
namedQuery){ W $E Ao+V
return getHibernateTemplate WN3]xw3
W}rL HAaDh
().findByNamedQuery(namedQuery); dA=T+u
} H#FH'@J
|$&v)
publicList findByNamedQuery(finalString query, F |^tRL-
Ae|bAyAK
finalObject parameter){ N5|wBm>m
return getHibernateTemplate ;noZmPa
<g'0q*qE
().findByNamedQuery(query, parameter); Xn*>qm
} }-2U,Xg[
f/3rcYR;y
publicList findByNamedQuery(finalString query, WdJJt2'
PIZK*Lop
finalObject[] parameters){ bPUldkB:
return getHibernateTemplate 35Cm>X
Bl/Z _@
().findByNamedQuery(query, parameters); rkWiGiisM
} 0W!S.]^1
#55_hY#
publicList find(finalString query){ $[{YE[a
return getHibernateTemplate().find ~Zo;LSI
">x"BP
(query); QM4O|x[
} 5"2pU{xmK
I,@
6w
publicList find(finalString query, finalObject re@;6o
rYPj3!#
parameter){ U_<k*o@:
return getHibernateTemplate().find /5"RedP<
RLR\*dL1
(query, parameter); UthM?g^
} ) 8 %lZ{
;(Kj-,>
public PaginationSupport findPageByCriteria ]qO*(m:}o
"`Y.5.
(final DetachedCriteria detachedCriteria){ UKzXz0
return findPageByCriteria =.2)wA"e'
wrAcVR
(detachedCriteria, PaginationSupport.PAGESIZE, 0); yyc4'j+
} &2,^CG
cd]def[d
public PaginationSupport findPageByCriteria -I.BQ
ewVks>lbz
(final DetachedCriteria detachedCriteria, finalint V* H7m'za
CMC9%uq
startIndex){ 6@-O#,]J
return findPageByCriteria KhZ\q|5
ChRCsu~
(detachedCriteria, PaginationSupport.PAGESIZE, R/Te;z
V~]&1
startIndex); j71RlS73
} qv)%)n
)Ag{S[yZ
public PaginationSupport findPageByCriteria _l=X?/
a3C\?5
(final DetachedCriteria detachedCriteria, finalint ,nSapmg
h]DzX8r}
pageSize, ]+d>;$O
finalint startIndex){ =PYS5\k
return(PaginationSupport) rFhi:uRV
{;+9A}e
getHibernateTemplate().execute(new HibernateCallback(){ l\HtP7]
publicObject doInHibernate G!E1N(%o
YSux#*#H
(Session session)throws HibernateException { %6E:SI4
Criteria criteria = Tzr'3m_
lD6PKZ\RIj
detachedCriteria.getExecutableCriteria(session); lt& c/xi_
int totalCount = o?S!o}
HleMzykF
((Integer) criteria.setProjection(Projections.rowCount jO}<W 1qy
ky I~
()).uniqueResult()).intValue(); E^? 3P'%^
criteria.setProjection h~s h!W8
>j)y7DSE
(null); 8SoTABHV
List items = V=)' CCi{
b}J,&eYD
criteria.setFirstResult(startIndex).setMaxResults Zqj EVVB
=i>i,>bv
(pageSize).list(); A>%mJ3M
PaginationSupport ps = 2<tU
Vr hd\
new PaginationSupport(items, totalCount, pageSize, XPT@ LM
a]@BS6
startIndex); z4 KKt&
return ps; -;iCe7|Twf
} U
U@
}, true); ahg]OWn#
} {9-n3j}
4DsHUc6
public List findAllByCriteria(final BVu{To:g
` NCH^)
DetachedCriteria detachedCriteria){ ;nAI;Qw L
return(List) getHibernateTemplate PLRMW2
k1~? }+<e
().execute(new HibernateCallback(){ |f2bb
publicObject doInHibernate naVbcY
3|=L1Pw#
(Session session)throws HibernateException { -
*v)sP"@
Criteria criteria = \{;3'<
G{gc]7\=Cd
detachedCriteria.getExecutableCriteria(session); >J/8lS{#
return criteria.list(); :H>0/^Mg0
} WkDXWv\{,{
}, true); ))4RgS$
} #3_
@aq*
m^>v~Q~~
public int getCountByCriteria(final l<:\w.Gl
:ka^ztXG
DetachedCriteria detachedCriteria){ J$i.^|hE/
Integer count = (Integer) \`R8s_S
{_UOS8j7
getHibernateTemplate().execute(new HibernateCallback(){ >DR$}{IV
publicObject doInHibernate vGwpDu\RgX
OJD!Ar8Q
(Session session)throws HibernateException { {\gpXVrn_
Criteria criteria = wY"BPl]b
p{AX"|QM"
detachedCriteria.getExecutableCriteria(session); A=r8_.@2@
return ]Rj?OSok
4@QR2K|
criteria.setProjection(Projections.rowCount =3EjD;2
DA>TT~L
()).uniqueResult(); f<M!L>+M6
} pd-I^Q3-
}, true); NRazI_Z
return count.intValue(); TT={>R[B
} lYS*{i1^ '
} t&~*!w!+jH
kAq#cLprG
r?/!VO-*N
10^FfwRfM
5]K2to)>`
b8!
用户在web层构造查询条件detachedCriteria,和可选的 ]I\9S{?
i5gNk)D
startIndex,调用业务bean的相应findByCriteria方法,返回一个 (wf3HEb_
D9!$H!T _
PaginationSupport的实例ps。 73JrK_h
xqfIm%9i}
ps.getItems()得到已分页好的结果集 9 dK`
ps.getIndexes()得到分页索引的数组 -_= m j
ps.getTotalCount()得到总结果数 Ey%KbvNv
ps.getStartIndex()当前分页索引 e-#Vs{?|r
ps.getNextIndex()下一页索引 g} pD%
ps.getPreviousIndex()上一页索引 0~ o,^AW
}ld^zyL
nd&i9 l
;,s9jw
vU$n*M1`$
e'->S g
=|dHD
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 z\$( @:{A
y9.?5#aL
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 jB`:(5%RO
;=WwJ Np~
一下代码重构了。 u:^sEk"Lk'
^PUB~P/
我把原本我的做法也提供出来供大家讨论吧: Z\cD98B#
"C?H:8W
首先,为了实现分页查询,我封装了一个Page类: e;2A{VsD8
java代码: txE+A/>i9
i! gS]?*DH
,T$ GOjt
/*Created on 2005-4-14*/ i.\ e/9]f
package org.flyware.util.page; }Rw6+;
i[:cG
/** BWNI|pq)v
* @author Joa 1 jO%\uR/
* cICfV,j
*/ Pm,.[5uc
publicclass Page { zQ#*O'-n
".2d{B
/** imply if the page has previous page */ 7D1$cmtH
privateboolean hasPrePage; %k~ezn
!qU1RdZ
/** imply if the page has next page */ $x,EPRNs
privateboolean hasNextPage; {e q378d
yDWBrN._
/** the number of every page */ @DF7j|]tV
privateint everyPage; g>k?03;
sG)aw`_j
/** the total page number */ w)B?j
privateint totalPage; r?!:%L
K:GEC-
/** the number of current page */ 'GT^araz
privateint currentPage; tP"6H-)X&
&FuL{YL
/** the begin index of the records by the current ('AAHq/
<XQwu*_\
query */ 53gLz_ee
privateint beginIndex; lcy<taNu)
/sj*@HF=
vbd)L$$20+
/** The default constructor */ v/=\(
public Page(){ szb@2fK
:0QDV~bs
} &9|L Z9K
1U/RMN3`
/** construct the page by everyPage ' QMcQvU
* @param everyPage l#%7BGwzY
* */ "j8)l4}
public Page(int everyPage){ W`NF4 0)
this.everyPage = everyPage; k!}(a0h
} qw?(^uZNW
\$*CXjh3G
/** The whole constructor */ %y|pVN!U
public Page(boolean hasPrePage, boolean hasNextPage, =&,T@5&-=
MfHOn YV
+ima$a0Zyt
int everyPage, int totalPage, o-7{\%+M
int currentPage, int beginIndex){ E #B$.K
this.hasPrePage = hasPrePage; elQjPvb
this.hasNextPage = hasNextPage; 6/5,n0
this.everyPage = everyPage; BAY e:0
this.totalPage = totalPage; 8'jt59/f
this.currentPage = currentPage; 1[8^JVC>6
this.beginIndex = beginIndex; NjpWK;L
} bxtH`^
[l3\0e6-/
/** -Dx3*Zh P
* @return =CJ`0yDQ>
* Returns the beginIndex. <kPNe>-f
*/ *1{A'`.=\
publicint getBeginIndex(){ 1n[)({OQ
return beginIndex; e15yDwvB
} #qYgQ<TM!
Qn.dL@W
/** t(6]j#5
* @param beginIndex z k/`Uz
* The beginIndex to set. dk
nM|
*/ tWTHyL
publicvoid setBeginIndex(int beginIndex){ 4
ZnQpKg
this.beginIndex = beginIndex; cx$h"
} )9_W"'V
R6od{#5H$
/** 3*~`z9-z
* @return wbAwmOiZ
* Returns the currentPage. rzIWQFv
*/ {VW\EOPV~
publicint getCurrentPage(){ eyJWFJh
return currentPage; T`":Q1n
} ))f@9m
PdqvXc
/** $<nRW*d
* @param currentPage Ig}hap]G
* The currentPage to set. L%/>Le}VX
*/ rHB>jN@$
publicvoid setCurrentPage(int currentPage){ wGNEb
this.currentPage = currentPage; x\8g ICf
} JAd .\2%Y
) hs&?:)
/** tj~r>SRb+
* @return H\oxj,+N
* Returns the everyPage. P|@[D=y
*/ ?V8Fgd
publicint getEveryPage(){ x5uz$g
return everyPage; v77UE"4|c
} ^3$U[u%q/{
9)v]jk
/** y EfAa6
* @param everyPage :XFQ}Cl
* The everyPage to set. _Sfu8k>):
*/ m`-:j"]b$
publicvoid setEveryPage(int everyPage){ #X'-/q`.
this.everyPage = everyPage; "$farDDoF
} ,]wQ]fpt
W7WHDL^
/** .8^mA1fmX
* @return "[~yu*
S
* Returns the hasNextPage. 8%m\J:eR
*/ en'[_43
publicboolean getHasNextPage(){ hzr,
%r
return hasNextPage; gU+yqT7=
} VQH48{X
,4xNW:!j
/** 2[`n<R\
* @param hasNextPage VVch%
* The hasNextPage to set. j[gqS%
*/ XLpn3sX$
publicvoid setHasNextPage(boolean hasNextPage){ ,H"}Rw
this.hasNextPage = hasNextPage; m<3. X"-
} J' P:SC1
'6qH@r4Z<
/** _0rt.NRD
* @return Ur< (TM
* Returns the hasPrePage. 0Sd>*nC
*/ h SS9mQ
publicboolean getHasPrePage(){ /]z#V'
return hasPrePage; @JhkUGG]p
} 4h!yh2c..
jRC{8^98
/** bS8$[7OhX
* @param hasPrePage ,0h{RZKw
* The hasPrePage to set. PU.j(0
*/ h\@X!Z,
publicvoid setHasPrePage(boolean hasPrePage){ {ObY1Y`ea
this.hasPrePage = hasPrePage; n]#YL4j
} 3Y)z{o>P
b*h:e.q
/** F~eYPaEKy!
* @return Returns the totalPage. P??P"^hU
* +sn0bi/rG
*/ kK}?NKqT
publicint getTotalPage(){ ,x&WE@tD|
return totalPage; igTs[q=Ak
} U`~L}w"
,/p+#|>C=
/** >wqWIw.w>
* @param totalPage OjffN'a+N
* The totalPage to set. {f4jE#a>v
*/ SbUac<
publicvoid setTotalPage(int totalPage){ C~>0K,C0^
this.totalPage = totalPage; j-J/yhWO&
} <bW~!lv
R$u1\r1I
} u8?$W%eW
<^>
nR3E
Xbx=h^S
w]xr
~D+
u{uqK7]+
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 MX#LtCG#V
b (HJ|
个PageUtil,负责对Page对象进行构造: t;3).F
java代码: :_HdOm
9f&
!Uw_W
(g[WZB3x
/*Created on 2005-4-14*/ EY)?hJS,
package org.flyware.util.page; I+Yq",{%
+pK 35u
import org.apache.commons.logging.Log;
N6BOUU]
import org.apache.commons.logging.LogFactory; AwuhFPG
*=O3kUoL
/** 2H8\P+
* @author Joa TEer>gD:v
* (O!CHN!:
*/ aEa.g.SZ
publicclass PageUtil { QaE!?R
#t Pc<p6m
privatestaticfinal Log logger = LogFactory.getLog <M5fk?n,|
mcQ
A'
(PageUtil.class); ?)<zzL",
5(1c?biP&
/** QS4~":D/C
* Use the origin page to create a new page k]-Q3V
* @param page 'bH~KK5
* @param totalRecords WCqa[=v)t
* @return =_N$0
*/ 9RSviIi$
publicstatic Page createPage(Page page, int /Trbr]lWy
b!J?>du
totalRecords){ * _usVg
return createPage(page.getEveryPage(), eq"Xwq*
NTK9`#SA
page.getCurrentPage(), totalRecords); %)d7iT~M
} 3
Sf':N`u
LtUw
/** GKUjtPu
* the basic page utils not including exception *(wxNsK
:T@} CJ
handler 1jBIi
* @param everyPage hhU\$'0B-
* @param currentPage ;5T}@4m|r
* @param totalRecords 23houS
* @return page Ks^wX
*/ {{pN7Z
publicstatic Page createPage(int everyPage, int 211T}a
(6}7z+
currentPage, int totalRecords){ |{,c2Ck:N
everyPage = getEveryPage(everyPage); |RXXj [z
currentPage = getCurrentPage(currentPage); \j.l1O
int beginIndex = getBeginIndex(everyPage, |h/{qpsu
sUiO~<Ozpk
currentPage); CZy3]O"qW
int totalPage = getTotalPage(everyPage, <wd;W;B
,5T1QWn^f
totalRecords); y
La E]
boolean hasNextPage = hasNextPage(currentPage, pP"j|
]j*uD317
totalPage); R S>qP;V*-
boolean hasPrePage = hasPrePage(currentPage); {+5Ud#\y
u2fp~.'P
returnnew Page(hasPrePage, hasNextPage, {}RU'<D
everyPage, totalPage, 1BP/,d |+
currentPage, ru1^.(W2
Gv#bd05X
beginIndex); S
{+Z.P
} M*Q}^<E*
BbL]0i
privatestaticint getEveryPage(int everyPage){ /m^G 99N
return everyPage == 0 ? 10 : everyPage; E1w8d4P,G
} 1IT(5Mleb
xBf->o S?
privatestaticint getCurrentPage(int currentPage){ X68.*VHh0
return currentPage == 0 ? 1 : currentPage; x]R0zol
} JnqP`kYbTE
/9Qr1@&v
privatestaticint getBeginIndex(int everyPage, int 1#fR=*ZM"
'0o^T 7C
currentPage){ <7L-25 =
return(currentPage - 1) * everyPage; 4?
rEO(SZ
} E]a;Ydf~
0pH$MkQ
privatestaticint getTotalPage(int everyPage, int uc]5p(9Hb
*xj2Z,u
totalRecords){ F,K))325
int totalPage = 0; -QBM^L
^q%f~m,O<
if(totalRecords % everyPage == 0) w?M"`O(
totalPage = totalRecords / everyPage; eIf-7S]m
else J*6B~)Sp@
totalPage = totalRecords / everyPage + 1 ; 0=40}n&`
*M>~$h7
return totalPage; y4=T0[
V
} ip*^eS^
@$%.iQ7A;
privatestaticboolean hasPrePage(int currentPage){ MhD=\Lpj\
return currentPage == 1 ? false : true; a^[s[j#^,
}
j>.1RG
Zz'g&ew