精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-12-03
最后修改:2008-12-12
<listbox id="userListBox" mold="paging" model="@{userList}" selectedItem="@{selectedUser}"> <listhead> <listheader label="登陆名" sort="auto" /> <listheader label="中文名" sort="auto" /> </listhead> <listitem self="@{each=user}"> <listcell label="@{user.loginname}" /> <listcell label="@{user.truename}" /> </listitem> </listbox> 用注释方式的数据绑定与直接用EL设置listbox的model属性对listbox来说都是把一个实现了org.zkoss.zul.ListModel 接口的对象赋值给listbox的model属性,唯一的区别就是注释方式还可以给listitem、listcell绑定数据,也就是说数据绑 定可以迭代 model并把每个model中的每个元素都与对应的listcell进行数据绑定,对应使用EL设置model的方式来说做同 样的事情还需要实现org.zkoss.zul.ListitemRenderer接口 。
把数据和listbos绑定在一起只是第1步,接下要用hibernate实现对数据库进行分页查询了。 给我留个言分享一下。注释数据绑定可以自动地把一个 java.util.List构造成ListModel的实现类,上面代码中的userList 就是一个java.util.List,实现分页查询的第二条思路就是从list下手,自己写一个能够使用hibernate实现分页的list,我 正是这样做的。 过hibernate查询出一个list来作为被代理的对象,这个list保存了本页要显示的数据,如果每页显示20条数据,那么这个 list的长度就是20,接着需要当前页最后一条记录序号保存起来,最后重写get方法,根据最后记录序号、每页显示条数判 断是否需要分页以及是向前翻页还是向后翻页。get方法的代码如下: @Override public Object get(int index) { if(index>=last||index<=last-limit*2){ this.fullData(index, limit); index = 0; if(list.size()==0) return null; else return list.get(index); }else{ index = index-(last-limit); if(list.size()==0) return null; else return list.get(index); } } 其中list就是被代理的对象,last就是最后一条记录的序号,limit是每页显示的记录数,fullData是具体执行分页查询的方 法。调用get时传入记录下标index如果大于等于最后一条记录的序号(记录序号是从1开始计数的)那么就向后翻页,如果 index小于等于上一页起始记录序号,那么需要向后翻页,不管是向后翻页还是向前翻页都需要重新查询从index到 index+limit的记录。数据实际上是放在被代理的list中的,要从被代理的list取出数据,那么下标始终是从0开始,所以需 要把这里传入的index转化成0开始的相对下标,下面就是进行转化的代码 index=index-(last-limit); 如果仅仅是对全表数据进行分页显示,这样做完全没有问题,但实际工作往往是需要对数据进行过滤的,也就是说这个分页 的list需要能够保证分页的时候能够执行带过滤条件的分页查询,所以这个分页list中用list来保存hibernate的Criterion对 象,在fullData新建一个criteria把这些Criterion都加进去。下面是fullData的代码: public void fullData(int start, int limit) { this.last = start + limit; this.limit = limit; list = new ArrayList(limit); SessionFactory sf = (SessionFactory) SpringUtil .getBean("sessionFactory"); Session session = sf.openSession(); Criteria criteria = session.createCriteria(clazz); for (Criterion crierion : listCriteria) { criteria.add(crierion); } criteria.setFirstResult(start); criteria.setMaxResults(start + limit); List result = criteria.list(); if (result != null) { Iterator iterator = result.iterator(); while (iterator.hasNext()) { list.add(iterator.next()); } } session.close(); } fullData还有一个重要的作用就是初始化被代理的list,这段代码都是hibernate的操作。 1、memberList.zul <?xml version="1.0" encoding="UTF-8"?> <?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?> <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="./demo"?> <window id="demo"> <zscript language="javascript" src="memberList.js"> </zscript> <groupbox id="main" mold="3d" width="100%"> <caption label="View"> <button label="新 增" height="18px" onClick="newUserWin.doModal();" /> <button label="查 询" height="18px" onClick="queryUserWin.doModal();" /> <button label="修 改" height="18px" onClick="updateUserWin.doModal();" /> </caption> <window id="userWin"> <listbox id="userListBox" mold="paging" model="@{memberList}" selectedItem="@{selectedMember}"> <listhead> <listheader label="登陆名" sort="auto" /> <listheader label="中文名" sort="auto" /> <listheader label="注册日期" sort="auto" /> </listhead> <listitem self="@{each=member}"> <listcell label="@{member.loginname}" /> <listcell label="@{member.truename}" /> <listcell label="@{member.registDate}" /> </listitem> </listbox> </window> </groupbox> <window id="newUserWin" visible="false" width="480px"> <groupbox mold="3d" width="100%"> <caption label="新增用户"></caption> <grid> <rows> <row> <label value="帐 号" /> <textbox id="user_loginname" value="@{member.loginname}" constraint="/.{2,4}/:长度在2,4之间" /> </row> <row> <label value="用户名" /> <textbox id="user_truename" value="@{member.truename}" /> </row> <row> <label value="密 码" /> <textbox id="user_password" value="@{member.password}" /> </row> </rows> </grid> <separator /> <hbox spacing="10px"> <space bar="false" spacing="10px" /> <button label="确 定" onClick="save()" /> <button label="取 消" onClick="newUserWin.setVisible(false);" /> </hbox> </groupbox> </window> <window id="queryUserWin" visible="false" width="480px"> <groupbox mold="3d" width="100%"> <caption label="查询用户"></caption> <grid> <rows> <row> <label value="帐 号" /> <textbox id="query_loginname" /> </row> <row> <label value="用户名" /> <textbox id="query_truename" /> </row> </rows> </grid> <separator /> <hbox spacing="10px"> <space bar="false" spacing="10px" /> <button label="查 询" onClick="javascript:query();" /> <button label="取 消" onClick="queryUserWin.setVisible(false);" /> </hbox> </groupbox> </window> <window id="updateUserWin" visible="false" width="480px"> <groupbox mold="3d" width="100%"> <caption label="修改用户"></caption> <grid> <rows> <row> <label value="帐 号" /> <textbox value="@{selectedUser.loginname}" /> </row> <row> <label value="用户名" /> <textbox value="@{selectedUser.truename}" /> </row> <row> <label value="密 码" /> <textbox value="@{selectedUser.password}" /> </row> </rows> </grid> <separator /> <hbox spacing="10px"> <space bar="false" spacing="10px" /> <button label="确 定" onClick="javascript:update();" /> <button label="取 消" onClick="updateUserWin.setVisible(false);" /> </hbox> </groupbox> </window> </window> 注意zul文件开头处理指令variable-resolver指定了org.zkoss.zkplus.spring.DelegatingVariableResolver来处理 EL中的变量,使用这个类可以在EL中直接使用spring定义的bean id,例如 <variables mService="${memberService}" /> 就是引用spring ApplictionContext中id为memberService的bean来定义名为mService的变量。init指令初始化了 org.zkoss.zkplus.databind.AnnotateDataBinderInit,这个类用来就是用来实现数据绑定的,至于是怎么实现的我 也不太清楚,只知道初始化后就可以使用数据绑定了。 2、memberList.js var member = new com.liyuan.spore.entity.Member(); var memberList = memberService.queryAllUser(); var selectedMember = memberList.get(0); function save(){ if(memberService.userIsExist(member.loginname)){ memberService.saveNewUser(member); newUserWin.setVisible(false); }else throw new WrongValueException(user_loginname, "账号已存在!"); } function query(){ var loginname=queryUserWin.getFellow("query_loginname").value; var truename=queryUserWin.getFellow("query_truename").value; var queryUser = new com.liyuan.spore.entity.Member(); if(!"".equals(loginname)) queryUser.setLoginname("%"+loginname+"%"); if(!"".equals(truename)) queryUser.setTruename("%"+truename+"%"); ulist = main.getFellow("userWin").getFellow("userListBox"); newList = new org.zkoss.zkplus.databind.BindingListModelList(memberService.query(queryUser),true); ulist.setModel(newList); selectedMember = newList.getElementAt(0); queryUserWin.setVisible(false); } function update(){ memberService.modify(selectedUser); } 第2行,调用memberService.queryAllUser()获取一个可以分页的list在memberList.zul中又通过注释的方式把数据绑 定到了listbox上。这里的memberService是直接通过org.zkoss.zkplus.spring.DelegatingVariableResolver引用 的spring ApplicationContext中定义的bean。 3、MemberService package com.liyuan.spore.zkdemo; import java.math.BigDecimal; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Example; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.liyuan.spore.entity.Member; @Service("memberService") @Scope("request") public class MemberService { private SessionFactory sessionFactory; @Autowired public void setSessionFactory(@Qualifier("sessionFactory") SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public PagingList queryAllUser() { Session session = sessionFactory.getCurrentSession(); Query query = session.createSQLQuery("select count(*) from T_MEMBER"); BigDecimal size = (BigDecimal) query.uniqueResult(); PagingList plist = new PagingList(Member.class, size.intValue()); plist.fullData(0, 20); return plist; } @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public boolean userIsExist(String loginname) { Session session = sessionFactory.getCurrentSession(); List list = session.createCriteria(Member.class).add( Restrictions.eq("loginname", loginname)).list(); return list.isEmpty(); } @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public void saveNewUser(Member user) { Session session = sessionFactory.getCurrentSession(); session.save(user); } @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public PagingList query(Member user) { Session session = sessionFactory.getCurrentSession(); Example example = Example.create(user); example.enableLike(); example.excludeZeroes(); example.excludeNone(); Criteria criteria = session.createCriteria(Member.class); criteria.setProjection(Projections.rowCount()).add(example); Integer size = (Integer) criteria.uniqueResult(); PagingList plist = new PagingList(Member.class, size.intValue()); plist.addCriterion(example); plist.fullData(0, 20); return plist; } @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public void modify(Member user) { Session session = sessionFactory.getCurrentSession(); session.update(user); } } 这段代码没有什么好解释的。 4、PagingList.java package com.liyuan.spore.zkdemo; import java.util.AbstractList; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Criterion; import org.zkoss.zkplus.spring.SpringUtil; public class PagingList extends AbstractList implements java.io.Serializable { private int last; private int limit; private int size; private Class clazz; private ArrayList list; private LinkedList<Criterion> listCriteria; public PagingList(Class entityClass, int theSize) { size = theSize; clazz = entityClass; listCriteria = new LinkedList<Criterion>(); last = 0; // fullData(0, 20); } public void setSize(int size) { this.size = size; } public void addCriterion(Criterion cr) { listCriteria.add(cr); } public void fullData(int start, int limit) { this.last = start + limit; this.limit = limit; list = new ArrayList(limit); SessionFactory sf = (SessionFactory) SpringUtil .getBean("sessionFactory"); Session session = sf.openSession(); Criteria criteria = session.createCriteria(clazz); for (Criterion crierion : listCriteria) { criteria.add(crierion); } criteria.setFirstResult(start); criteria.setMaxResults(start + limit); List result = criteria.list(); if (result != null) { Iterator iterator = result.iterator(); while (iterator.hasNext()) { list.add(iterator.next()); } } session.close(); } @Override public Object get(int index) { if (index >= last || index <= last - limit * 2) { this.fullData(index, limit); index = 0; if (list.size() == 0) return null; else return list.get(index); } else { index = index - (last - limit); if (list.size() == 0) return null; else return list.get(index); } } @Override public int size() { return size; } @Override public int hashCode() { int hashCode = 1; Iterator i = list.iterator(); while (i.hasNext()) { Object obj = i.next(); hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); } return hashCode; } @Override public int indexOf(Object o) { return list.indexOf(o); } @Override public Iterator iterator() { // TODO Auto-generated method stub return list.iterator(); } @Override public ListIterator listIterator() { return list.listIterator(); } @Override public ListIterator listIterator(int index) { return list.listIterator(index); } @Override public Object remove(int index) { return list.remove(index); } @Override public Object[] toArray() { return list.toArray(); } public void removeCriterions() { this.listCriteria.clear(); } } 这段代码就是可以分页的list,和hibernate高度耦合,但是对于单一实体的分页查询是可以重用的。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-12-11
你好哈,能把这个例子的源码放上来吗?我正在学习zk。谢谢
|
|
返回顶楼 | |
发表时间:2008-12-12
这位大哥 ,谢谢哈
|
|
返回顶楼 | |
发表时间:2008-12-12
谢谢楼主拉,最近正在研究,正好用上
|
|
返回顶楼 | |
发表时间:2009-06-28
恩最近我也在研究 Zk不过这文章写了有半年了!
还是很值得一看的! 但是好像zk商业应用用的很少啊! |
|
返回顶楼 | |
浏览 7625 次