Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造 f|~ {j(.v
p2i?)+z
detachedCriteria,然后调用业务层Bean,进行动态条件查询,根 {}$7B p
EyE#x_A
据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来 w>&*-}XX
w31Ox1>s
自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改 QkdcW>:a7
hu.o$sV3;
。 :lcq3iFn
^!&6=rb
分页支持类: d}[cX9U/
v\Uk?V5T
java代码: +1!iwmch>
Kf[d@L
x?+w8jSR
package com.javaeye.common.util; 'j6O2=1
mLxgvp
import java.util.List; "0P`=n
q*l4h u%3
publicclass PaginationSupport { tg/UtE`V
V*uE83x1
publicfinalstaticint PAGESIZE = 30; |1~n<=`Z
'p&,'+x
privateint pageSize = PAGESIZE; #hZ$;1.
6:7[>|okQ
privateList items; ;=ddv@
,_Z(!|
rW
privateint totalCount; /uwi$~Ed
_qxI9Q}<"
privateint[] indexes = newint[0]; J~k9jeq9
5 8bW
privateint startIndex = 0; Rqh5FzB>
,yYcjs!=o
public PaginationSupport(List items, int 4N,mcV
y>P+"Z.K%}
totalCount){ $oK&k}Q
setPageSize(PAGESIZE); CJ
:V %|
setTotalCount(totalCount); !qt2,V
setItems(items); Pb#M7=J/
setStartIndex(0); mH'~pR>t
} 8b2 =n
}X&rJV
public PaginationSupport(List items, int 6Yj{%
G
uZ!YGv0^
totalCount, int startIndex){ Gmz^vpQ]t
setPageSize(PAGESIZE); 0@
Y#P|QF
setTotalCount(totalCount); AG N/kx
setItems(items); to'7o8Z
setStartIndex(startIndex); +3)r
szb72
} :aesG7=O
E#B-JLMGl
public PaginationSupport(List items, int ?l0eU@rwQ
Lnr9*dm6q
totalCount, int pageSize, int startIndex){ Iux3f+H
setPageSize(pageSize); J7`mEL>?
setTotalCount(totalCount); +xFn~b/
setItems(items); [0 F~e
setStartIndex(startIndex); $.SBW=^V
} \#{PV\x:Nn
@NiuT%#c
publicList getItems(){ \CL8~
return items; ANM#Kx+
} C$OVN$lL`8
2%W;#oi?
publicvoid setItems(List items){ D0D=;k
this.items = items; BzzC|
} 513,k$7
4Z"}W!A
publicint getPageSize(){ O
*sU|jeO
return pageSize; EhcJE;S)
} `\kihNkJn3
|kYlh5/c d
publicvoid setPageSize(int pageSize){ ] G&*HMtp
this.pageSize = pageSize; b(iF0U>&
} )kpEcMlR
'NEl`v*<P
publicint getTotalCount(){ u^"
I3u8$
return totalCount; \Z[1m[{
} d1<";b2Jt^
?[ xgt)
publicvoid setTotalCount(int totalCount){ Hr|f(9xA
if(totalCount > 0){ -*C
WF|<G
this.totalCount = totalCount; IOy0WHl|
int count = totalCount / &9L4
t%As
5R7x%3@L
pageSize; v@_1V
if(totalCount % pageSize > 0) mci> MEb
count++; G{U#9
indexes = newint[count]; IiU> VLa
for(int i = 0; i < count; i++){ 7' G;ijx
indexes = pageSize * J2bvHxb Rd
]juPm8eF
i; X3.zNHN5
} 0a~t
}else{ nf.Ox.kM)
this.totalCount = 0; -@pjEI
} VW-qQe
} )PX VR
T
-'! J?~
publicint[] getIndexes(){ 77P\:xc
return indexes; <J/ =$u/
} ma.84~m
hbw(o
publicvoid setIndexes(int[] indexes){ "tJ+v*E
this.indexes = indexes; Z>hTL_|]a{
} ;*A'2ymXUT
#-/W?kD
publicint getStartIndex(){ nBh+UT}
return startIndex; 4Uy% wB
} dljE.peL
3_(_yEKx
publicvoid setStartIndex(int startIndex){ .WSyL
if(totalCount <= 0) u,^CFws_
this.startIndex = 0; l2D*b93
elseif(startIndex >= totalCount) LP2~UVq
this.startIndex = indexes [h/T IGE\
;Shu
[indexes.length - 1]; @- U\!Tf
elseif(startIndex < 0) _D '(R
this.startIndex = 0; [&)]-2w2
else{ 5\ mRH
this.startIndex = indexes uYh!04u
02;jeZ#z
[startIndex / pageSize]; akj<*,
} a=z] tTs4
} osW"wh_
>B BV/C'9
publicint getNextIndex(){ )(iv#;ByL
int nextIndex = getStartIndex() + g`XngRb|j
W }NUU
pageSize; ~tDYo)hH8
if(nextIndex >= totalCount)
aJu&h2G
return getStartIndex(); @!8aZB3odt
else TEtmmp0OD
return nextIndex; c+Q'4E0|
} ++cS^ Lo
dWAt#xII
publicint getPreviousIndex(){ kf,
&t
int previousIndex = getStartIndex() - T5XXC1+
MpV<E0CmE
pageSize; /bo}I-<2
if(previousIndex < 0) Z)?$ZI@
return0; YQBLbtn6(
else V6]6KP#D
return previousIndex; [Vd$FDki
} cgnNO&
6u[fCGi%
} 3I6ocj[,
$7x2TiAL
s8h*nZ)v
+QChD*
抽象业务类 #:K=zV\
java代码: gabfb#
8z=#
0+0
77>oQ~q
/** 8mI(0m'
* Created on 2005-7-12 Y;i=c6
*/ o) )` "^
package com.javaeye.common.business; }EK{UM9y
<,i4Ua
import java.io.Serializable; 5'2kP{;
import java.util.List; RSX27fb4
9YzV48su#
import org.hibernate.Criteria; Ge^`f<f
import org.hibernate.HibernateException; H 4<"+7
import org.hibernate.Session; %OQdUH4x
import org.hibernate.criterion.DetachedCriteria; X9x`i
import org.hibernate.criterion.Projections;
.-gJS-.c
import D,#UJPyg
#{i*9'
org.springframework.orm.hibernate3.HibernateCallback; waMF~#PJlt
import WAu>p3
NxP(&M(
org.springframework.orm.hibernate3.support.HibernateDaoS &:&'70Ya
lC<;Q*Y
upport; 'zyw-1
}(EH5jZ'
import com.javaeye.common.util.PaginationSupport; e3I""D{)[=
G m~ ./-
public abstract class AbstractManager extends `DM%a~^yg
sf*4|P}
HibernateDaoSupport { Sd7jd ?#9'
!=0h*=NOYt
privateboolean cacheQueries = false; N'
hT
lY%I("2=
privateString queryCacheRegion; N>mW64_H)
'uL4ezTtA
publicvoid setCacheQueries(boolean (x=$b(I
F*72g)hVh
cacheQueries){ RQVu~7d[
this.cacheQueries = cacheQueries; VjQ&A#
} H 0l1=y
gV_v5sk
publicvoid setQueryCacheRegion(String q*I*B1p[m
UU=]lWib
queryCacheRegion){ "@V yc6L
this.queryCacheRegion = *22Vc2[i;
xyL"U*
queryCacheRegion; Z.VKG1e}
} 0 R6:3fV6R
U1\7Hcs$
publicvoid save(finalObject entity){ 4 m:h&^`N
getHibernateTemplate().save(entity); X[B P0:`t
} R)NSJ-A!2
!%>RHh[
publicvoid persist(finalObject entity){ h"FI]jK|}
getHibernateTemplate().save(entity); $1f2'_`8~
} BgQEd@cN
g'.OzD
publicvoid update(finalObject entity){ ;1k&}v&
getHibernateTemplate().update(entity); C`5'5/-.
} yl[I'fX66
Ss[[V(-
publicvoid delete(finalObject entity){ -WC0W
getHibernateTemplate().delete(entity); j|!,^._i
} 4BCPh:
(Pc>D';{S
publicObject load(finalClass entity, Fh #QS'[
$/wm k7T
finalSerializable id){ e]4$H.dP
return getHibernateTemplate().load 2<D| {
$ XjijD9R
(entity, id); \n<!
ld
} { 'b;lA]0
5m8u :6kQu
publicObject get(finalClass entity, <)7aNW.
gAAC>{Wh
finalSerializable id){ D<WnPLA$g
return getHibernateTemplate().get :[0 R F^2}
5kGniG?T#
(entity, id); F0$w9p
} ale'-V)5
Fp\;j\pfw
publicList findAll(finalClass entity){ )qy?x7
return getHibernateTemplate().find("from VN`.*B|9[
2KLMFI.F
" + entity.getName()); ~I||"$R
} @KQ>DBWQM
EI_-5Tt RD
publicList findByNamedQuery(finalString >wW{$
mnm
ZO}
namedQuery){ ]Lv3XMa
return getHibernateTemplate )eZK/>L&
ocGrB)7eD
().findByNamedQuery(namedQuery); 8$IKQNS
} H/o_? qK
>@vu;j\*E5
publicList findByNamedQuery(finalString query, b-u@?G|<
9nFL70
finalObject parameter){ Sn nfU
return getHibernateTemplate _3Eo{^
u)@:V)z
().findByNamedQuery(query, parameter); $qD\ku;'
} m23"xnRB
63l3WvoK
publicList findByNamedQuery(finalString query, NLy4Z:&{
}UPC~kC+Z
finalObject[] parameters){ t^01@ejM+
return getHibernateTemplate q T6y&
"OLg2O^
().findByNamedQuery(query, parameters); q`xc h[H
} v>8.TE~2
^4`aONydl
publicList find(finalString query){ 0qS/>u*
return getHibernateTemplate().find sOhn@*X
Qs1CK;+zU
(query); u
W]gBhO$O
} <K CI@
5r5on#O&
publicList find(finalString query, finalObject P@v"aa\@2)
a_b#hM/c;
parameter){ Fb{N>*l.
return getHibernateTemplate().find $1.-m{Bd
<^YvgQ,m
(query, parameter); Yq ]sPE92
} D;en!.[Z
m.D8@[y
public PaginationSupport findPageByCriteria x?S86,RW
FX!KX/OE)
(final DetachedCriteria detachedCriteria){ |[`YGA4
return findPageByCriteria !)bZ.1o
7O55mc>cF
(detachedCriteria, PaginationSupport.PAGESIZE, 0); 9&sb,^4
} 0YiTv;mq;
5]&sXs
public PaginationSupport findPageByCriteria }O\IF}X
Lm[,^k
(final DetachedCriteria detachedCriteria, finalint M-@RgWvF
ZID- ~
6
startIndex){ o;@~uU
return findPageByCriteria pS$9mzY
cN@_5
(detachedCriteria, PaginationSupport.PAGESIZE, J4+K)gWB
4X^$"lM
startIndex); {Z2nc)|7C
} p{,#H/+J
5aaM;45C
public PaginationSupport findPageByCriteria (.UU40:t
0/v]YK.
(final DetachedCriteria detachedCriteria, finalint qSP&Fi
p7QZn.,=u
pageSize, &g;!n&d zP
finalint startIndex){ qur2t8gnxq
return(PaginationSupport) |y^=(|eM
c^I^jg2v
getHibernateTemplate().execute(new HibernateCallback(){ o< @![P
publicObject doInHibernate 4aArxJ
ao)';[%9s
(Session session)throws HibernateException { B@*b 9
Criteria criteria = ]W;6gmV
%,WH*")
detachedCriteria.getExecutableCriteria(session); ~u&gU1}
int totalCount = a,w|r#x]
7<su8*?
((Integer) criteria.setProjection(Projections.rowCount >ZJ]yhbhK
*v%y;^{k[/
()).uniqueResult()).intValue(); wG49|!l6T
criteria.setProjection *H!BThft4
Q/g!h}>(.
(null); pg%(6dqK4
List items = lpXGsKH2
glLVT
i
criteria.setFirstResult(startIndex).setMaxResults W{-g?)Tou
lqfTF
(pageSize).list(); Rq|6d
M6H
PaginationSupport ps = )
A:h
b-
- tl@H
new PaginationSupport(items, totalCount, pageSize, JOuyEPy
opH!sa@U
startIndex); Lf((
zk:pt
return ps; 3RaW\cWzg
} _^W;J/He
}, true); U;W9`JT<.f
} nF'YG+;|@
P!]uJ8bi
public List findAllByCriteria(final _tHhS@
M z&/.A
DetachedCriteria detachedCriteria){ X$5
return(List) getHibernateTemplate (
unmf,y
<\O+
().execute(new HibernateCallback(){ -)(5^OQ
publicObject doInHibernate 1(@$bsgu2
c:m=9>3
(Session session)throws HibernateException { !S=YM<A d
Criteria criteria = \2kLj2!
&%rM|
detachedCriteria.getExecutableCriteria(session); Xr
<H^X
return criteria.list(); l_}d Q&R
} |RL#BKC`
}, true); `h@fW- r
} \96\!7$@O
Zp)=l Td
public int getCountByCriteria(final $w*L'
<
O[VY|.MEk
DetachedCriteria detachedCriteria){ O&<p
8
Integer count = (Integer) <yipy[D
F
,472H
getHibernateTemplate().execute(new HibernateCallback(){ >OaD7
publicObject doInHibernate &IN%2c
Y'iI_cg
(Session session)throws HibernateException { }@q/.Ct! x
Criteria criteria = WGz)-IB!PE
k&ooV4#f6
detachedCriteria.getExecutableCriteria(session); ]qqgEZ1!Y
return rnZ$Qk-H
aqEZhMy
criteria.setProjection(Projections.rowCount lQ?jdi
e ymv/
()).uniqueResult(); Kn:Ml4[;
} #DgHF*GG+>
}, true); e%cTFwX?n
return count.intValue(); l
L;5*@
} Nbr$G=U
} :e7\z
o,WjM[e
9" q-Bb
,40OCd!
],SQD3~9
Ysu\CZGX
用户在web层构造查询条件detachedCriteria,和可选的 CFh9@Nx
jh oA6I
startIndex,调用业务bean的相应findByCriteria方法,返回一个 fz^j3'!\
$Wj= V
PaginationSupport的实例ps。 }T4|Kyu?
/:F^*]
ps.getItems()得到已分页好的结果集 M/6Z,oOU
ps.getIndexes()得到分页索引的数组 6 ]x?2P%
ps.getTotalCount()得到总结果数 .yy-jf/
ps.getStartIndex()当前分页索引 ?C[?dg{n
ps.getNextIndex()下一页索引 ]P3m=/w
ps.getPreviousIndex()上一页索引 12lX-~[["
MoFM'a9
(|BY<Ac3
Ip'tB4Mq
E<\$3G-do
bqED5;d'#
nx'c=gp
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错 O=3/qs6m
\I!mzo
,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做 0cycnOd
m}'_Poc
一下代码重构了。 XX/gS=NE#.
ZHK>0>;
我把原本我的做法也提供出来供大家讨论吧: ;Xt<\^e
%[$HX'Y
首先,为了实现分页查询,我封装了一个Page类: 7,SQz6]
java代码: gNEcE9y2
{K.H09Y
yus3GqPI
/*Created on 2005-4-14*/ a6LL]_&g
package org.flyware.util.page; n- 2X?<_Z
>IIq_6Z#
/** To*+Z3Wd
* @author Joa fF)Q;~_VA
* bKpy?5&>
*/ +b-ON@9]J`
publicclass Page { cp@Fj"
1@v<
/** imply if the page has previous page */ <}J!_$A
privateboolean hasPrePage; `xzKRId0
B4b'0p
/** imply if the page has next page */ |H
t5a.
privateboolean hasNextPage; z&gmaYwq
(S!UnBb&
/** the number of every page */ kxhsDD$@p
privateint everyPage; 59oTU
B2[f1IMI
/** the total page number */ }i!+d,|f
privateint totalPage; .rK0C)
OV]xo8a;
/** the number of current page */ <gwRE{6U
privateint currentPage; Q|)>9m!tt
%NQ%6B
/** the begin index of the records by the current ,LA'^I?
R0=f` ;
query */ `a&L
privateint beginIndex; <2)AbI+3
2G~{x7/[@
eaFkDl
/** The default constructor */ hTDGgSG^
public Page(){ I:jIChT
naaKAZ!S
} |<c9ZS+
,7s>#b'
/** construct the page by everyPage w<H Xe
* @param everyPage qO"QSSbZqQ
* */ G^ GIHdo
public Page(int everyPage){ ATkd# k%S
this.everyPage = everyPage; nG'Yo8I^5
} B!Wp=9)G
X)!XR/?
/** The whole constructor */ 9Q1%+zjjMq
public Page(boolean hasPrePage, boolean hasNextPage, sg,\!'
` &A`&-nc=
,w~3K%B4
int everyPage, int totalPage, 50MM05aC
int currentPage, int beginIndex){ Tm`@5
this.hasPrePage = hasPrePage; Yd3lL:M
this.hasNextPage = hasNextPage; ]S%_&ZMCM
this.everyPage = everyPage; -
jZAvb
this.totalPage = totalPage; B[ZQn]y
this.currentPage = currentPage; nDvfb*\
this.beginIndex = beginIndex; sc]#T)xG
} qefp3&ls
Gt*<Awn8
/** :z8/iD y
* @return zh2<!MH
* Returns the beginIndex. 'f{13-#X@
*/ q(qm3OxYo
publicint getBeginIndex(){ c= t4 gf
return beginIndex; c6F?#@?
} =u2~=t=LV
|>(Vo@
/** Wq3PN^
* @param beginIndex h^(U:M=A
* The beginIndex to set. T)e2IXGN
*/ fc~fjtqwvz
publicvoid setBeginIndex(int beginIndex){ D]E=0+
this.beginIndex = beginIndex; H}r]j\
} h>bjG
2;sTSGDG
/** %/3+:}@G
* @return 4vL\t
uoz
* Returns the currentPage. O + aK#eF
*/ qVh?%c1.Y
publicint getCurrentPage(){ MX]#|hEeQ
return currentPage; 7D<Aa?cv_l
} "=Z=SJ1D
h~Ir=JV
/** |$/#,Dv7
* @param currentPage @rT$}O1?`
* The currentPage to set. F2zo
!a8
*/ oqvu8"
publicvoid setCurrentPage(int currentPage){ 93n%:?l"<W
this.currentPage = currentPage; nN&dtjoF
} M;XU"8
fa]8v6
/** Ia%cc
L=
* @return Mcc%&j
* Returns the everyPage. 3DO*kM1s@
*/ J?{sTj"KB
publicint getEveryPage(){ 9 5!xJdq
return everyPage; ED8{
} (tA[] ne2
P>q~ocq<
/** U>kaQ54/
* @param everyPage (A2ga):Pk
* The everyPage to set. jk`U7G*
*/ ?MywA'N@x
publicvoid setEveryPage(int everyPage){ .~I:Hcf/
this.everyPage = everyPage; :Jyr^0`J
} Pm P&Qje7
GdC=>\]
/** <!t;[ie?y
* @return Gu{1%bb#kL
* Returns the hasNextPage. fUvXb>f,
*/ kDJYEI9j>
publicboolean getHasNextPage(){ JQ
?8yl
return hasNextPage; x(>XM:|
} *As"U99(
J,v024TM
/** b6;MTz*k>
* @param hasNextPage ~Q"qz<WO
* The hasNextPage to set. !]R>D{""
*/ B0RVtbK
publicvoid setHasNextPage(boolean hasNextPage){ v "2A?
this.hasNextPage = hasNextPage; MX*4d{ l
} lre(]oBXA
,&,XcbJ
/** _H U>T
* @return {6LS$3}VM
* Returns the hasPrePage. !}|'1HIC
*/ N\ <riS9
publicboolean getHasPrePage(){ }qGd*k0F0
return hasPrePage; wy|b Hkr_
} i*l=xW;bM
:
HU|BJ>
/** [2Y@O7;nI
* @param hasPrePage @sa_/LH!K
* The hasPrePage to set. TyO]|Q5
*/ y z3=#
publicvoid setHasPrePage(boolean hasPrePage){ ^VzhjKSu
this.hasPrePage = hasPrePage; 7lYf+&JZ
} pbh>RS=ri
}x6)}sz7
/** "w 4^i!\
* @return Returns the totalPage. LTx,oa:ma
* @}^VA9ULK
*/ `<@ "WSn
publicint getTotalPage(){ E}zGY2Xx
return totalPage; I7h v'3u
} pQZ`dS\
!`H!!Kg0L
/** B !x6N"
* @param totalPage BQ,749^S
* The totalPage to set. f^}n#
*/ 4<<eqxI$|
publicvoid setTotalPage(int totalPage){ Wf?[GO
this.totalPage = totalPage; ?W dY{;&
} KWYjN
h#*
C5KUIOg
} k g(}%Ih
asQ^33g z
modem6#x'
',Z]w;D!G
Z @DDuVr
上面的这个Page类对象只是一个完整的Page描述,接下来我写了一 5l,Lp'k
wKcuIc$
个PageUtil,负责对Page对象进行构造: {Gh9(0,B?
java代码: CE
(zt
$<VH~Q<
_`*G71PS
/*Created on 2005-4-14*/ //3fgoly
package org.flyware.util.page; `"V}Wq ?I
-j Nnx*
import org.apache.commons.logging.Log; 1uyd+*/(xP
import org.apache.commons.logging.LogFactory; _b)Ie`a.H
hBz>E 4mEv
/** .i;?8?
* @author Joa Dg Rn^gL{Q
* wKpD++k
*/ mq}uq9<
publicclass PageUtil { o=zl{tZV
wqjR-$c
privatestaticfinal Log logger = LogFactory.getLog r~|7paX!
ifl
LY7j
(PageUtil.class); dBM{]@bZ
^;{uop"DS
/** Y#P!<Q>}
* Use the origin page to create a new page P=P']\`p+
* @param page =~,2E;#X
* @param totalRecords ES(qu]CjI
* @return 6h)
&h1Yd
*/ c<Ud[x.
publicstatic Page createPage(Page page, int 1JOoICjB
>`yRL[c;
totalRecords){ [k%u$
return createPage(page.getEveryPage(), 0XC3O 8q
,1t|QvO
page.getCurrentPage(), totalRecords); 2/F8kVx{
} '"hSX=
;i [;%
/** oFzmH!&ED
* the basic page utils not including exception Fo0s<YlS-
SgN?[r)
handler vXM{)
* @param everyPage 39pA:3iTd
* @param currentPage EKuLt*a/
* @param totalRecords sw:a(o&$
* @return page m.gv?
*/ ; Ob^@OM
publicstatic Page createPage(int everyPage, int ]W`M
<hEI
8F$]@0v`%
currentPage, int totalRecords){ j5smmtM`s
everyPage = getEveryPage(everyPage); Vvv;m 5.
currentPage = getCurrentPage(currentPage); Ofb&W
AD
int beginIndex = getBeginIndex(everyPage, ,t*H: *
>~'z%
currentPage); szqR1A
int totalPage = getTotalPage(everyPage, mtLiS3Nk8
(6
RWI#
totalRecords); zDxJK
boolean hasNextPage = hasNextPage(currentPage, ,CB E&g
5]kv1nQ
totalPage); XQOM6$~,
boolean hasPrePage = hasPrePage(currentPage); }:s.m8LC5n
Xe\v6gbD
returnnew Page(hasPrePage, hasNextPage, #Hl?R5
everyPage, totalPage, L|'B*
currentPage, 05jjLM'e
zG%'Cw)8
beginIndex); bx-:aC)]2
} _$ 8:\[J
JPZH%#E(
privatestaticint getEveryPage(int everyPage){
# xX
return everyPage == 0 ? 10 : everyPage; @'Pay)P
} `0+-:sXZ6
)g^O'e=m
privatestaticint getCurrentPage(int currentPage){ pUu<0a^
return currentPage == 0 ? 1 : currentPage; 4)XB3$<
} T}"[f/:N/
}P\6}cK
privatestaticint getBeginIndex(int everyPage, int 3".#nN
D mky!Cp
currentPage){ ,sg\K>H=
return(currentPage - 1) * everyPage; [4yw? U
} P*ZMbAf.
=L?2[a$2;
privatestaticint getTotalPage(int everyPage, int ^oE#;aS
u2[L^]|
totalRecords){ d+
[2Sm(7
int totalPage = 0; :N_DJ51
7e#|Iq:o
if(totalRecords % everyPage == 0) C/9]TkX}q
totalPage = totalRecords / everyPage; CZ{7?:^f
else ^/}&z