Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 dj}|EW4
nZM]EWn
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 u9 5D0S
qpzyl~g:C
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 M !X^2
(EH}lh}%
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 @z:E]O}
L uW""P/
。 B~b
='jN
uMRzUK`QK
分页支持类: 40z1Qkmaey
,W;|K 5
java代码: Bn.5ivF3
\jZ)r>US"
24wr=5p]Q
package com.javaeye.common.util; K[x=knFO
;wTc_i
import java.util.List; 8idI Jm%y
@LSX@V
publicclass PaginationSupport { u|k_OUTq
f{uS
publicfinalstaticint PAGESIZE = 30; ;f=.SJF
GL,[32~C
privateint pageSize = PAGESIZE; gSf> +|
^z~drcR
privateList items; 1 |/ |Lq%w
8~T=p:z'
privateint totalCount; tY:,9eh7B
_xBhMu2f
privateint[] indexes = newint[0]; Aj(y]p8
ZE1${QFkG
privateint startIndex = 0; B>sQcZ:
hjhZ":I.
public PaginationSupport(List items, int t_Rj1U
?{xD{f$
totalCount){ 43 <i3O
setPageSize(PAGESIZE); |?hsMN
setTotalCount(totalCount); 8k+k\V{
setItems(items); `b%^_@Fb
setStartIndex(0); D *IeG>%
} K@Xj)
lkC| g%f
public PaginationSupport(List items, int |C5{[ z
Z,"YMUl'
totalCount, int startIndex){ F?ps?
e
setPageSize(PAGESIZE); hegH^IN M
setTotalCount(totalCount); ej1WkaR8
setItems(items); B?Rkz
setStartIndex(startIndex); :_`Yrx5
} (:h&c6'S)b
=W>a ~e]/
public PaginationSupport(List items, int <fA}_BH%]
e E(+
totalCount, int pageSize, int startIndex){ 0QxBC7`qp
setPageSize(pageSize); &}K%F)S
setTotalCount(totalCount); if3z Fh
setItems(items); O@w_"TJP/z
setStartIndex(startIndex); PWquu`
} u9u'5xAO
] mK{E~Zll
publicList getItems(){ (f~}5O<
return items; 4W<[& )7
} :nfy=*M#
1=ZQRJW0B
publicvoid setItems(List items){ k_?~@G[I
this.items = items; `tcX[(`
} ]24]id
B\%
Gp}
publicint getPageSize(){ B~J63Os/
return pageSize; @;KvUR/+FE
} Dz/MIx
5 PP^w~n
publicvoid setPageSize(int pageSize){ 9[DlJ@T}
this.pageSize = pageSize; ePxAZg$ `>
} *)oBE{6D
`B,R+==G:
publicint getTotalCount(){ >6IUle>z
return totalCount; x}=Q)|)]
} DF-.|-^9I
B}K<L\S
publicvoid setTotalCount(int totalCount){ J,s:CBCGL
if(totalCount > 0){ FMzG6nrdBN
this.totalCount = totalCount; 6&L;Sw#Dg
int count = totalCount / @\>7
wt_'
P
m&^rC;
pageSize; 5H|7DVG
if(totalCount % pageSize > 0) =WEDQ\ c
count++; ` .]oH1\
indexes = newint[count]; nT(AO-Ue^
for(int i = 0; i < count; i++){ I1s$\NZ~]
indexes = pageSize * lhf5[Rp
l)'*jZ
i; QIJ/'72
} i [Wxu M
}else{ {XD':2E
this.totalCount = 0; D 5:'2i
} "v0SvV<7
} hW6Ksn,*
c `.BN(
publicint[] getIndexes(){ 77wod}h!:
return indexes; -3 "<znv
} ^g"p}zf
L"
Vi0D>4{+
publicvoid setIndexes(int[] indexes){ QjYw^[o
this.indexes = indexes; v yt|x5
} L|;sB=$'{
ZF8`=D`:R
publicint getStartIndex(){ FPPl^
return startIndex; rEbH<|
} Vock19P
7(P4KvkI
publicvoid setStartIndex(int startIndex){ ub+XgNO
if(totalCount <= 0) Xn>>hzj-x?
this.startIndex = 0; pRUQMPn (
elseif(startIndex >= totalCount) 6z:/ma^
this.startIndex = indexes SwaPRAF
{.DY\;Q
[indexes.length - 1]; ^+k= ;nl
elseif(startIndex < 0) ou`KkY||
this.startIndex = 0; qG9j}[d'
else{ Y^;izM}
this.startIndex = indexes z\?<j%e!t
rfzzMV
[startIndex / pageSize]; +Hp`(^(
} hF`<I.z}
} 'tU \~3k
| h+vdE8
publicint getNextIndex(){ A5]yC\*zt
int nextIndex = getStartIndex() + e<FMeg7n
Z`zLrXPD)
pageSize; 4X+I2CD
if(nextIndex >= totalCount) d>Nh<PqH6
return getStartIndex(); >+>N/`BG
else %?[0G,JG
return nextIndex; m`]d`%Ex
} o02G:!gB
}U4mXkZF
publicint getPreviousIndex(){ iM9^.
int previousIndex = getStartIndex() - oTcf[<
EWv[Sp
pageSize; ;d_<6|*M
if(previousIndex < 0) <=w!:
return0; !4 lN[
else 4gWlSm)
return previousIndex; u,N<U t
} ]1W]
"<%J^Z9G
} -(ST
tF./Jx]_
6UL9+9[C
obPG]*3
抽象业务类 }7P[%(T5
java代码: p{``a=
GCv1x->
_>?.MUPB
/** Pf?15POg&B
* Created on 2005-7-12 4 ?[1JN>
*/ joZd
package com.javaeye.common.business; 8pp;"
"b
KGI<G
import java.io.Serializable; V7O7"Q^q
import java.util.List;
:Gx5vo
W/~q%\M {
import org.hibernate.Criteria; )UVekkq>Q
import org.hibernate.HibernateException; V?p`rrj@
import org.hibernate.Session; |`{$Ego:
import org.hibernate.criterion.DetachedCriteria; i
XGy*#>V
import org.hibernate.criterion.Projections; e#k)F.TZ:%
import >l=^3B,j
IY
mkZ?cW
org.springframework.orm.hibernate3.HibernateCallback; _{eA8J(A<
import G-;EB
?du*ITim
org.springframework.orm.hibernate3.support.HibernateDaoS '
~fP#y
3"k n5)x
upport; 3SPXJa\i
6K=}n] n
import com.javaeye.common.util.PaginationSupport; r}:U'zlC{
-z
se+]O`
public abstract class AbstractManager extends UFUEY/q
a0Fq$
HibernateDaoSupport { -%{+\x2
9U=6l]Np
privateboolean cacheQueries = false; 5P 5Tgk
cR*~JwC:
privateString queryCacheRegion; AEElaq.B
{MDM= ;WP_
publicvoid setCacheQueries(boolean ]#G1
]U
FT-=^VA\
cacheQueries){ }n'W0Sa
this.cacheQueries = cacheQueries; t)~$p#NS
} V{x[^+w7X~
tYSfeU
publicvoid setQueryCacheRegion(String LX=v
_}l
J
s~o\j/
queryCacheRegion){ 9|OOT[
this.queryCacheRegion = nQa:t. rC
YIb7y1\UM
queryCacheRegion; 'm-5
} c"t&,OU:
!67xN?b
publicvoid save(finalObject entity){ ;lhW6;oI'
getHibernateTemplate().save(entity); P 6=5:-Hh
} ^),t=!;p
;W FiMM\
publicvoid persist(finalObject entity){ ez5>V7Y
getHibernateTemplate().save(entity); yMD0Tj5ZQ
} /V#?d
:C,}DyZy
publicvoid update(finalObject entity){ -pQ?ybQ
getHibernateTemplate().update(entity); E0DquVrz
} giW9b_
=U8+1b
publicvoid delete(finalObject entity){ )a`kL,
getHibernateTemplate().delete(entity); g@Y]$ey%A
} uf:'"7V7
K*4ib/'E a
publicObject load(finalClass entity, Q:b0!
HNlW.y"
finalSerializable id){ 2:e7'}\D.
return getHibernateTemplate().load CteNJBm
Z/4bxO=m
(entity, id); Z$6B}cz<
} ];N/KHeZ
PpF`0w=1%l
publicObject get(finalClass entity, LZE9]Gd
IMzt1l
=7
finalSerializable id){ =e9<.{]S/
return getHibernateTemplate().get a( N;|<
<54KWC86)J
(entity, id); ocp
} `G:hC5B
2=1qmQE
publicList findAll(finalClass entity){ H6`zzH0"
return getHibernateTemplate().find("from F"3'~6
lZ <D,&
" + entity.getName()); pigu]mj
} SxcE@WM
wub7w#
publicList findByNamedQuery(finalString %*IH~/Ld;]
`49!di[
namedQuery){ }h8U.k?v
return getHibernateTemplate Lc "{ePFh
w]V684[>
().findByNamedQuery(namedQuery); G9K& }_,
} 8H8Q
\]\ h,Y8
publicList findByNamedQuery(finalString query, K2V?[O#
t? =V<Yd1
finalObject parameter){ lEb H4 g
return getHibernateTemplate $~?)E;S
e:_[0#
().findByNamedQuery(query, parameter); |W&K@g$
} EZhk(LE
z=8l@&hYLq
publicList findByNamedQuery(finalString query, {BJH}vV1)
\{ C
~B;=
finalObject[] parameters){ !d[]Qt%mA
return getHibernateTemplate tq=M 9c
54RexB o
().findByNamedQuery(query, parameters); -Y N(j\
} M*~X pT3
#]^M/y
h
publicList find(finalString query){ f3:dn7
return getHibernateTemplate().find ]5MT-qU
u9]M3>
(query); Mt%Q5^
} I7t}$S6
Qkw_9
publicList find(finalString query, finalObject BV\~Dm]"
:X7O4?ww
parameter){ 2|`Mb~E;
return getHibernateTemplate().find /1= x8Sb
C/ ]Bx
(query, parameter); ;$qc@)Uwp
} ?}u][akM
[d>2F
public PaginationSupport findPageByCriteria {e0aH `me
!thFayq
(final DetachedCriteria detachedCriteria){ Z0wH%o\
return findPageByCriteria U2\k7I
H;Gs0Qi;
(detachedCriteria, PaginationSupport.PAGESIZE, 0); 2_Cp}Pj
} Lg2PP#r
y\dx \
public PaginationSupport findPageByCriteria &hZ6CV{
"39mhX2
(final DetachedCriteria detachedCriteria, finalint 2j1HN
4e?c W&
startIndex){ |]-~yYqP3
return findPageByCriteria eQqCRXx
|t#s h
(detachedCriteria, PaginationSupport.PAGESIZE, &rc
r>-
uF)^mT0D=
startIndex); eq9qE^[Z&
} :cP u
UM0#S}
public PaginationSupport findPageByCriteria Kf$6D 79#
\fYPz }wt
(final DetachedCriteria detachedCriteria, finalint |47 2X&e
[:A">eYI
pageSize, 2%`8
finalint startIndex){ {WeRFiQ?-
return(PaginationSupport) jX t5.9 t
\oP
getHibernateTemplate().execute(new HibernateCallback(){ i9peQ61{
publicObject doInHibernate M,Lq4 bz
f.R;<V.)
(Session session)throws HibernateException { R m2M
Criteria criteria = n~i^+pD@
'p%w_VbI
detachedCriteria.getExecutableCriteria(session); =H}}dC<)
int totalCount = YC*`n3D|'
DnF|wS
((Integer) criteria.setProjection(Projections.rowCount -YipPo"a
4%<D\#
()).uniqueResult()).intValue(); u}?{1B!
criteria.setProjection ?b]f$
2
0zA:?}
(null); '6T *b
List items = ksYPF&l
fECmELd
criteria.setFirstResult(startIndex).setMaxResults `_J>R
*kJa$3*r
(pageSize).list(); owO&[D/
PaginationSupport ps = pT;xoe
SNH AL F
new PaginationSupport(items, totalCount, pageSize, .e5rKkkT
M%Q_;\?]
startIndex); [-#q'S
return ps; ,awkL
:
} ]:4\rBR3
}, true); 6%&w\<(SG
} 3tmS/tQp
G4uOY?0N
public List findAllByCriteria(final RggZ'.\
4HGR-S/
DetachedCriteria detachedCriteria){ krXU*64
return(List) getHibernateTemplate 01+TVWKX
9}d^ll&
().execute(new HibernateCallback(){ ?A 5;"
publicObject doInHibernate $oi8<8Y
p4Xhs@.k
(Session session)throws HibernateException { s>ZlW:jY
Criteria criteria = H*&!$s.
_2<d6@}
detachedCriteria.getExecutableCriteria(session); #|
m*k
return criteria.list(); j<A; i
} HU-#xK
}, true); =K9-
} n<>]7-
en16hd>^W:
public int getCountByCriteria(final 4?aNJyV%&
.[vYT.LE
DetachedCriteria detachedCriteria){ (gUxS.zU
Integer count = (Integer) .wcKG9u
? UBE0C
getHibernateTemplate().execute(new HibernateCallback(){ B|-W
publicObject doInHibernate Jrx]/CM
;QQ/bM&I
(Session session)throws HibernateException { >]?!9@#IH
Criteria criteria = cb _nlG!
r} a,
detachedCriteria.getExecutableCriteria(session); jp#/]>(9Z
return
lD?]D&
PKt;]T0
criteria.setProjection(Projections.rowCount qk!,:T
/m+.5Qz9)@
()).uniqueResult(); *En4~;l
} #h2 qrX&+
}, true); !F#^Peb
return count.intValue(); eu?DSad
} 8"J6(KS
} 8|IlJiJ~v
0|`iop%(n
nbSu|sX~r5
6G?7>M
a O(&<
Zs}EGC~&
用户在web层构造查询条件detachedCriteria,和可选的 ~{np G
QPp>%iE@
startIndex,调用业务bean的相应findByCriteria方法,返回一个 vN`JP`IBx
RJA#cv~f
PaginationSupport的实例ps。 Ct9*T`Gl
=}YaV@g<f
ps.getItems()得到已分页好的结果集 6g%~~hX
ps.getIndexes()得到分页索引的数组 0tP{K
ps.getTotalCount()得到总结果数 .jbT+hhM
ps.getStartIndex()当前分页索引 [knwp$
ps.getNextIndex()下一页索引 ,M$J
yda
ps.getPreviousIndex()上一页索引 {@T<eb$d
S)G*+)
3+WostOx
Xm[Cgt_?
q%8Ck)xz
K{]\}7+
1_G5uHO
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 aDjYT/`l
kaZ_ra;<
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 teg[l-R"7z
pDG>9P#mO
一下代码重构了。 bn0Rv
aq%i:};
我把原本我的做法也提供出来供大家讨论吧: iGsD!2
)TyI~5>;
首先,为了实现分页查询,我封装了一个Page类: |FJc'&) J"
java代码: !jyy`q=
Rln@9muXA
"!_,N@\t
/*Created on 2005-4-14*/ rd4mAX6@
package org.flyware.util.page; P(Q}r7F~(
3"iJ/Hc}9
/** }i@%$Ixsn
* @author Joa &cB+la\_
* x_.}C%
*/ T6Ks]6m_
publicclass Page { 8WMGuv
ue"e><c6:
/** imply if the page has previous page */ vB1nj<]&z
privateboolean hasPrePage; gatxvR7H
h9WyQl7
/** imply if the page has next page */ ;$rh&ET
privateboolean hasNextPage; nSeb?|$D 6
}} wZ
/** the number of every page */ R'x^Y"
privateint everyPage; u4.2u}A/R%
}R2afTn[;
/** the total page number */ H(F9&6}
privateint totalPage; &=hkB9
;
7xjihl3
/** the number of current page */ n%={!WD
privateint currentPage; [,|;rt\o>
`& }C*i"
/** the begin index of the records by the current vON1\$bu`
cK~VNzsz
query */ 3pI)
privateint beginIndex; U~YjTjbd
yh"48@L'D
pl5Q2zq%
/** The default constructor */ pJPP6Be<
public Page(){ W,sPg\G 3
UWg+7RL
} l. 0|>gj`0
x]<0Kq9K
/** construct the page by everyPage L<H6AzR+
* @param everyPage EGJrnz8
* */ m005*>IY
public Page(int everyPage){ /faP@Q3kR
this.everyPage = everyPage; y`p(}X`>
} &U0Y#11Cx
5qQ\ H}
/** The whole constructor */ Gjo&~*;
public Page(boolean hasPrePage, boolean hasNextPage, nj5Hls
l\1_v7s
&1,{.:@e
int everyPage, int totalPage, WiCJhVF3
int currentPage, int beginIndex){ Qvhz$W[P>
this.hasPrePage = hasPrePage; 7F
1nBd
this.hasNextPage = hasNextPage; TM^.y
Y
this.everyPage = everyPage; +IPMI#n
this.totalPage = totalPage; >`u/#mrd
this.currentPage = currentPage; g,d'&r"JWt
this.beginIndex = beginIndex; b{hdEb
} _/)HAw?k
_V_GdQ
/** hxx`f-#=
* @return 1i:Q
%E
F
* Returns the beginIndex. TC^fyxq
*/ T +~
_D
publicint getBeginIndex(){ AN
'L-
E
return beginIndex; L(w?.)E
} =>,X)+O
px=r~8M9}
/** %6HJM| {H
* @param beginIndex k9 NPC"
* The beginIndex to set. g RBbL1
*/ F=r`'\JV[
publicvoid setBeginIndex(int beginIndex){ o1]Ze F
this.beginIndex = beginIndex; h^=9R6im
} RqRyZ*n
Nr:%yvk%s
/** {'1e?
* @return muKCCWy#
* Returns the currentPage. !0!r}#P
*/ #5}v?
publicint getCurrentPage(){ 7bC)Co#:
return currentPage; { K*
} 9>hK4&m^
TxXX}6
/** m. "T3K
* @param currentPage El4SL'E@
* The currentPage to set. BhC>G2 ^7
*/ !+Us) 'L
publicvoid setCurrentPage(int currentPage){ e]@R'oM?#`
this.currentPage = currentPage; w^wh|'u^_@
} J^)=8cy
"=vH,_"Ql
/** y?.l9
* @return NB?y/v
* Returns the everyPage. z{ MO~d9
*/ yjj)+eJ(Q
publicint getEveryPage(){ (H-}z`sy/@
return everyPage; ~e#QAaXD#5
} Q]<6i
"6zf-++%
/** ry!0~ir
* @param everyPage zaMKwv}BR
* The everyPage to set. J1gLT $
*/ VAet!H +]
publicvoid setEveryPage(int everyPage){ m.2=,,r<Fq
this.everyPage = everyPage; JPGEE1!B{b
} ISALR{Aq
Z@ZSn0
/** \:|"qk
* @return @w{"6xc%a
* Returns the hasNextPage. &JHqUVs^
*/ ypV>*
publicboolean getHasNextPage(){ '7(oCab"_
return hasNextPage; Os"T,`F2s
} !@wG22iC4d
8lfKlXR78
/** 2(iv+<t
* @param hasNextPage u RPvo}!=1
* The hasNextPage to set. %% A==_b
*/ *e}1KcJ
publicvoid setHasNextPage(boolean hasNextPage){ -G@:uxB
this.hasNextPage = hasNextPage; jpRC6b?
} 6qH^&O][
d
gRTV<vM
/** o=ULo &9
* @return I!;vy/r
* Returns the hasPrePage. YqNI:znm-
*/ 5BsfbLKC
publicboolean getHasPrePage(){ T f;:C]
return hasPrePage; 3}25=%;[
} n+%tu"e
cLyed3uU
/** fZF.eRP'
* @param hasPrePage `(Ij@84
* The hasPrePage to set. 7zEpuw
*/ NQ qq\h
publicvoid setHasPrePage(boolean hasPrePage){ Q3|I.I e
this.hasPrePage = hasPrePage; lJ/{.uK
} h(MS>=
MR-cO Pn
/** @1^:V-=
* @return Returns the totalPage. E!zAUEVQm[
* T,SCK^
*/ PuoN<9 #
publicint getTotalPage(){ ZKco
return totalPage; _ pKWDMB$z
} m.DC
JDj^7\`
/** VaLl$w
* @param totalPage f%cbBx^;
* The totalPage to set. IM9P5?kJ
?
*/ SlojB ^%
publicvoid setTotalPage(int totalPage){ V^ 5Z9!
this.totalPage = totalPage; =V*4&OU
} R'1L%srTM+
5KvqZ1L
} 2z615?2_U
pSh$#]mZ`
ti}G/*4
11jDAA(|
}&:F,q*
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 n 9N'}z
Y:'#jY*V
个PageUtil,负责对Page对象进行构造: ygSvYMC
java代码: h(Ccm44
v'X=|$75
T^XU5qgN
/*Created on 2005-4-14*/ \B1<fF2
package org.flyware.util.page; ?QfomTT
^":Dk5gl
import org.apache.commons.logging.Log; +KKx\m*
import org.apache.commons.logging.LogFactory; K}1eQS&$a
Sw^-@w=!U5
/** ]`GDZw`
* @author Joa *&sXC@^@^
* Oxq} dX7S
*/ * Qe{CE
publicclass PageUtil { Z5%T pAu[
r(ufyC&
privatestaticfinal Log logger = LogFactory.getLog >HlQ+bl$xw
n^7m^1to
(PageUtil.class); W99Hq1W;r
xFy%&SKHg
/** 08JVX'X-mr
* Use the origin page to create a new page .vJt&@NO
* @param page _z(ydL*
* @param totalRecords UZ}>@0
* @return qc6eqE
*/ EU@XLm6
publicstatic Page createPage(Page page, int )}i;OLw-
Q1(6U6L
totalRecords){ Vuu_Sd
return createPage(page.getEveryPage(), KQ\d$fX
TDnbX_xC<
page.getCurrentPage(), totalRecords); P 2^((c
} .ugQH<B
Yt%
E,U~g
/** ZUxlk+o9d
* the basic page utils not including exception 4hh=z>$|l)
O)i]K`jk
handler </B5^}
* @param everyPage Jb4A!g5C
* @param currentPage UZq1qn@+
* @param totalRecords jQ[M4)>_k`
* @return page +HxL>\
*/ OlI {VszR
publicstatic Page createPage(int everyPage, int RIQw+RG>
Ul?92
currentPage, int totalRecords){ %B{NH~
everyPage = getEveryPage(everyPage); &?@5G
currentPage = getCurrentPage(currentPage); wBK%=7
int beginIndex = getBeginIndex(everyPage, `*hrU{b
;\gsd'i
currentPage); CWk65tcF
int totalPage = getTotalPage(everyPage, b+`mh
>4lT0~V/
totalRecords); _Z|3qQ
boolean hasNextPage = hasNextPage(currentPage, |+0XO?,sZ
F&I ;E i
totalPage); .0zNt
boolean hasPrePage = hasPrePage(currentPage); "p{cz(
_hb@O2f
returnnew Page(hasPrePage, hasNextPage, YN@4.&RP
everyPage, totalPage, wWNHZv&
currentPage, |,wp@)e6h
z
nc'
beginIndex); T)NnWEB
} "RF<i3{S
j7M[]/|
privatestaticint getEveryPage(int everyPage){ &]? X"K
return everyPage == 0 ? 10 : everyPage;
G$"$k=[
} <_tkd3t#W
7~V,=WEe
privatestaticint getCurrentPage(int currentPage){ ?]#U~M<'
return currentPage == 0 ? 1 : currentPage; u< ,c
} Q/,jv5
_@47h86Q
privatestaticint getBeginIndex(int everyPage, int $"/xi `
4mY(* 2:HC
currentPage){ 1L=6Z2*fB4
return(currentPage - 1) * everyPage; G#pRBA^
} u{o!#_o64
e:~r_,K
privatestaticint getTotalPage(int everyPage, int iJ rF$Xw
{G
D<s))
totalRecords){ 2AAZZx +$
int totalPage = 0; R]7-6
DPD%8a)?
if(totalRecords % everyPage == 0) 07_ym\N
totalPage = totalRecords / everyPage; xD(JkOne
else SOI$Mx
totalPage = totalRecords / everyPage + 1 ; %dMP}k/
#iOoi9(
return totalPage; |GvWHe`
} O,kzU,zOs
ho7L@NR
privatestaticboolean hasPrePage(int currentPage){ {i7Wp$ug
return currentPage == 1 ? false : true; L.uX
} ByrK|lVM0
&O