Chinaunix首页 | 论坛 | 博客
  • 博客访问: 89166
  • 博文数量: 2
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 280
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-13 11:32
文章分类
文章存档

2008年(2)

我的朋友

分类: Java

2008-03-17 22:57:20

在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) |
0

上一篇:没有了

下一篇:封装 log4cpp 加上函数名等跟踪信息

给主人留下些什么吧!~~