在WEB页面中显示数据,经常需要用到分页算法。
我的做法是分两步:
第一步,进行第一次数据库操作,读取记录集的总数,用于显示分页总数等数据;
第二步,进行第二次数据库操作,读取指定了偏移量的记录集;
实例说明:以下例子,数据取自2个表的关联。
表1为 UserInfo,用户数据表,包含以下数据:
userId:用户Id编号,主键;
status:用户状态,例如数值1标识为正常状态;
loginId:用户名,唯一值;
name:用户姓名;
表2为 AdminInfo,管理员数据表,包含以下数据:
userId:用户Id编号,即与 UserInfo.userId 作为关联字段;
getAdminCount 函数接受一个字串 keyword ,用于过滤记录集;代码如下:
代码中用到了2个表关联,如果对单表操作,就更简单了,读者自行处理吧
public Integer getAdminCount(String keyword) throws HibernateException { Integer count = null; Session session = getSession(); Transaction tx = session.beginTransaction(); try { Criteria criteria = session.createCriteria(AdminInfo.class); criteria = criteria.createAlias("userInfo", "userInfo");
criteria.add(Restrictions.eq("userInfo.status", 1));
if (!"".equals(keyword)) { keyword = "%" + keyword + "%";
criteria.add(Restrictions.or(Restrictions.like( "userInfo.loginId", keyword.toUpperCase()), Restrictions.like("userInfo.name", keyword))); }
criteria.setProjection(Projections.rowCount());
count = (Integer) (criteria.list().iterator().next());
tx.commit(); } catch (HibernateException e)
{ log.error("catch exception:", e);
if (tx != null) { tx.rollback(); }
throw e; }
return count; }
|
以上代码中,蓝色粗体下划线部分提示了读取记录集总数的操作实现方法。
接着是 getAdminList 用于取得相应记录集,除传递上面的 keyword 外,还需要传递记录集的偏移量(即所需要取得的记录集的开始位置),及所需要读取的记录集的大小。
@SuppressWarnings("unchecked") public List<AdminInfo> getAdminList(String keyword, int offset, int size) throws HibernateException { Session session = getSession(); Transaction tx = session.beginTransaction();
List<AdminInfo> list = null;
try { Criteria criteria = session.createCriteria(AdminInfo.class); criteria = criteria.createAlias("userInfo", "userInfo");
criteria.add(Restrictions.eq("userInfo.status", 1));
if (!"".equals(keyword)) { keyword = "%" + keyword + "%";
criteria.add(Restrictions.or(Restrictions.like( "userInfo.loginId", keyword.toUpperCase()), Restrictions.like("userInfo.name", keyword))); }
criteria.setFirstResult(offset); criteria.setMaxResults(size);
list = (List<AdminInfo>) criteria.list();
tx.commit(); } catch (HibernateException e) { log.error("catch exception:", e);
if (tx != null) { tx.rollback(); }
throw e; }
return list; }
|
以上代码中,蓝色粗体下划线部分提示了读取指定范围记录集的操作实现方法。
附上 AdminInfo.hbm.xml ,供读者参考2表关联映射关系的写法:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" ""> <hibernate-mapping package="reader.pojo"> <class name="AdminInfo" table="tblAdminInfo"> <id name="userId" column="userId" type="integer"/> <many-to-one name="userInfo" class="UserInfo" column="userId" insert="false" update="false" fetch="select" cascade="none"/> </class> </hibernate-mapping>
|
最后是一个 formatOffset 函数,用于修正用户在选取分页时输入的 offset 值。这个函数在 get count 和 get list 之间使用。
public static int formatOffset(Integer offset, int count, int pageSize) { if (offset == null || count == 0) { return 0; }
if (offset % pageSize != 0) { offset = offset - (offset % pageSize); }
if (offset < count) { return offset; }
int remainder = count % pageSize; if (remainder == 0) { return count - pageSize; }
return count - remainder; }
|
现在可以在 struts action 中使用了,实例代码如下
DynaValidatorForm vform = (DynaValidatorForm) form; String keyword = (String) vform.get("keyword"); Integer offset = (Integer) vform.get("offset");
MemberAdo memberAdo = new MemberAdo();
Integer count = memberAdo.getAdminCount(keyword);
offset = Misc.formatOffset(offset, count, 10); vform.set("offset", offset);
List<AdminInfo> adminList = memberAdo.getAdminList(keyword, offset, 10);
request.setAttribute("adminList", adminList); request.setAttribute("offset", offset); request.setAttribute("count", count); request.setAttribute("pageSize", 10);
|
数据取读完成了,最后一步就是在JSP显示数据了,JSP代码略。
阅读(1309) | 评论(0) | 转发(0) |