Spring+Hibernate+Struts2项目 分页显示算法实现

分页显示一直是web开发中一大烦琐的难题,传统的网页设计只在一个JSP或者ASP页面中书写所有关于数据库操作的代码,那样做分页可能简单一点,但当把网站分层开发后,分页就比较困难了,下面是我做Spring+Hibernate+Struts2项目时设计的分页代码,与大家分享交流。

 1、DAO层接口的设计,在MemberDao接口中定义了如下两个方法:

public interface MemberDao {

   @SuppressWarnings("unchecked")

   /**

    * 分页查询

    * @param hql查询的条件

    * @param offset开始记录

    * @param length一次查询几条记录

    * @return

    */

   public List queryForPage(final String hql,finalint offset,finalint length);

   /**

    * 查询所有记录数

    * @param hql查询的条件

    * @param offset开始记录

    * @return总记录数

    */

   public int getAllRowCount(String hql);

}

2、DAO层实现类MemberDaoImpl对上面两个方法的实现如下:

public class MemberDaoImpl extends HibernateDaoSupportimplements MemberDao {

   /**

    * 查询所有记录数

    * @return总记录数

    */

   public int getAllRowCount(String hql) {

      return getHibernateTemplate().find(hql).size();

   }

 

   /**

    * 分页查询

    * @param hql查询的条件

    * @param offset开始记录

    * @param length一次查询几条记录

    * @return

    */

   @SuppressWarnings("unchecked")

   public List queryForPage(final String hql,final int offset,final int length) {

      List list = getHibernateTemplate().executeFind(newHibernateCallback(){

         public Object doInHibernate(Session session)

                throws HibernateException, SQLException {

            Query query = session.createQuery(hql);

            query.setFirstResult(offset);

            query.setMaxResults(length);

            List list = query.list();

            return list;

         }

      });

      return list;

   }

}

细心的读者会发现,这个类继承了HibernateDaoSupport类,HibernateDaoSupport是Spring提供的对Hibernate支持的类,getHibernateTemplate().executeFind(new HibernateCallback(){....})方法中的参数,我们使用了接口回调,在其参数内,我们能像原生的Hibernate一样调用query.setFirstResult(offset)和query.setMaxResults(length)来实现分页查询功能。

3、下面我们来新建一个保存分页信息的类PageBean,具体代码如下:

 

public class PageBean {

   @SuppressWarnings("unchecked")

   private Listlist;   //要返回的某一页的记录列表

   private int allRow //总记录数

   private int totalPage //总页数

   private int currentPage //当前页

   private int pageSize; //每页记录数

   @SuppressWarnings("unused")

   private boolean isFirstPage //是否为第一页

   @SuppressWarnings("unused")

   private boolean isLastPage //是否为最后一页

   @SuppressWarnings("unused")

   private boolean hasPreviousPage //是否有前一页

   @SuppressWarnings("unused"

   private boolean hasNextPage; //是否有下一页


   @SuppressWarnings("unchecked")

   public List getList() {

      return list;

   }

   @SuppressWarnings("unchecked")

   public void setList(List list) {

      this.list = list;

   }

   public int getAllRow() {

      return allRow;

   }

   public void setAllRow(int allRow) {

      this.allRow = allRow;

   }

   public int getTotalPage() {

      return totalPage;

   }

   public void setTotalPage(int totalPage) {

      this.totalPage = totalPage;

   }

   public int getCurrentPage() {

      return currentPage;

   }

   public void setCurrentPage(int currentPage) {

      this.currentPage = currentPage;

   }

   public int getPageSize() {

      return pageSize;

   }

   public void setPageSize(int pageSize) {

      this.pageSize = pageSize;

   }

   public void setFirstPage(boolean isFirstPage) {

      this.isFirstPage = isFirstPage;

   }

   public void setLastPage(boolean isLastPage) {

      this.isLastPage = isLastPage;

   }

   public void setHasPreviousPage(boolean hasPreviousPage) {

      this.hasPreviousPage = hasPreviousPage;

   }

   public void setHasNextPage(boolean hasNextPage) {

      this.hasNextPage = hasNextPage;

   }

   //初始化分页信息

   public void init(){

      this.isFirstPage = isFirstPage();

      this.isLastPage = isLastPage();

      this.hasPreviousPage = isHasPreviousPage();

        this.hasNextPage = isHasNextPage();

   }

   //部分set方法

   public boolean isFirstPage() {

      return currentPage == 1;  // 如是当前页是第1

   }

   public boolean isLastPage() {

      return currentPage == totalPage //如果当前页是最后一页

   }

   public boolean isHasPreviousPage() {

      return currentPage!=1;  //只要当前页不是第1

   }

   public boolean isHasNextPage() {

      return currentPage != totalPage //只要当前页不是最后1

   }

   /**

    * 计算总页数,静态方法,供外部直接通过类名调用

    * @param pageSize 每页记录数

    * @param allRow 总记录数

    * @return 总页数

*/

   public static int countTotalPage(finalint pageSize,finalint allRow){

      int totalPage = allRow % pageSize == 0 ? allRow/pageSize :allRow/pageSize+1;

      return totalPage;

   }

   /**

    * 计算当前页开始记录

    * @param pageSize 每页记录数

    * @param currentPage 当前第几页

    * @return当前页开始记录号

    */

   public static int countOffset(finalint pageSize,finalint currentPage){

      final int offset = pageSize * (currentPage-1);

      return offset;

   }

   /**

    * 计算当前页,若为0或者请求的URL中没有"?page=",则用1代替

    * @param page 传入的参数(可能为空,0,则返回1)

    * @return 当前页

    */

   public static int countCurrentPage(int page){

      final int curPage = (page==0?1:page);

      return curPage;

   }

}

4、Service层接口的设计:

public interface MemberService {

 

   /**

    * 分页查询

    * @param pageSize每页大小

    * @param currentPage当前第几页

    * @return封闭了分页信息(包括记录集list)Bean

    */

   public PageBean queryForPage(int pageSize,int currentPage);

}

5、Service层实现类的部分内码如下:

public class MemberServiceImpl implements MemberService{

 

   private MemberDaomemberDao;

   public MemberDao getMemberDao() {

      return memberDao;

   }


   public void setMemberDao(MemberDao memberDao) {

      this.memberDao = memberDao;

   }

 

   /**

    * 分页查询

    * @param currentPage当前第几页

    *  @param pageSize每页大小

    *  @return封闭了分页信息(包括记录集list)Bean

    */

   @SuppressWarnings("unchecked")

   public PageBean queryForPage(int pageSize,int currentPage) {

      final String hql ="fromUser"; //查询语句

      int allRow =memberDao.getAllRowCount(hql); //总记录数

      int totalPage = PageBean.countTotalPage(pageSize,allRow);//总页数

      final int offset = PageBean.countOffset(pageSize,currentPage);//当前页开始记录

      final int length = pageSize;   //每页记录数

      List<MemberService> list = memberDao.queryForPage(hql, offset, length);//"一页"的记录

      

       //把分页信息保存到bean

       PageBean pageBean = new PageBean();

      pageBean.setPageSize(pageSize);

      pageBean.setCurrentPage(currentPage);

      pageBean.setAllRow(allRow);

      pageBean.setTotalPage(totalPage);

       pageBean.setList(list);

       pageBean.init();

      return pageBean;

   }

}

 6、在Struts2中调用queryForPageMemberService层的queryForPage()方法即可return一个包含分页信息、符合条件的结果集list,代码如下:

public class ListMemberAction extends ActionSupport {

   private MemberServicememberService;

    private int page = 1; //第几页

    private PageBeanpageBean; //包含分布信息的bean

   

   public MemberService getMemberService() {

      return memberService;

   }

   public void setMemberService(MemberService memberService) {

      this.memberService = memberService;

   }

   public int getPage() {

      return page;

   }

   public void setPage(int page) {

      this.page = page;

   }

   public PageBean getPageBean() {

      return pageBean;

   }

   public void setPageBean(PageBean pageBean) {

      this.pageBean = pageBean;

   }

   @Override

   public String execute()throws Exception {

      //分页的pageBean,参数pageSize表示每页显示记录数,page为当前页

      this.pageBean =memberService.queryForPage(2, page);

      return "success";

   }

}

7、最后在listMember.jsp页面中,用到了Struts2标签:

<s:iteratorvalue="pageBean.list">

      <s:property value="title"/>

      <a href="getArticle.action?id=<s:propertyvalue="id"/>">modify</a>

      <a href="deleteArticle.action?id=<s:propertyvalue="id"/>" οnclick="returnaskDel()"/>delete</a><br/>

    </s:iterator>

    共<s:property value="pageBean.allRow"/> 条记录

    共<s:property value="pageBean.totalPage"/> 页

    当前第<s:property value="pageBean.currentPage"/>页<br/>

    

    <s:if test="%{pageBean.currentPage == 1}">

      第一页上一页

    </s:if>

    <s:else>

      <a href="listMyArticle.action?page=1">第一页</a>

      <a href="listMyArticle.action?page=<s:propertyvalue="%{pageBean.currentPage-1}"/>">上一页</a>

    </s:else>

    <s:if test="%{pageBean.currentPage !=pageBean.totalPage}">

      <a href="listMyArticle.action?page=<s:propertyvalue="%{pageBean.currentPage+1}"/>">下一页</a>

      <a href="listMyArticle.action?page=<s:propertyvalue="pageBean.totalPage"/>">最后一页</a>

    </s:if>

    <s:else>

      下一页最后一页

    </s:else>

 

到这里,Hibernate+Spring+Struts2整合开发中的分页问题就已经解决了,

配置文件:

8、Struts:配置文件

<?xmlversion="1.0"encoding="UTF-8"?>

  <!DOCTYPEstrutsPUBLIC

       "-//Apache Software Foundation//DTD StrutsConfiguration 2.1//EN"

      "http://struts.apache.org/dtds/struts-config_2_1.dtd">

 <struts>

     <!-- 可以动态调用方法

     <constantname="struts.enable.DynamicMethodInvocation" value="false"/>

      -->

     <!-- 设置为开发模式  true自动加载 -->

     <constantname="struts.devMode"value="true"/>

     <!-- 解决中文乱码问题 -->

     <constantname="struts.i18n.encoding"value="GBK"/>

     <!-- 将创建对象的控制权交给spring -->

     <constantname="objectFactory"value="spring"></constant>

    

     <packagename="login"namespace="/"extends="struts-default">

       <actionname="show"class="login">

          <resultname="success">/show/listMember.jsp</result>

       </action>

     </package>

  </struts>

9Hibernate配置文件,映射文件和实体类代码省略。

10、Spring配置文件:

<!-- 配置hibernate路径 -->

   <beanid="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

      <propertyname="configLocation"value="classpath:hibernate.cfg.xml"></property>

   </bean>

   <!-- action -->

   <beanname="login"class="action.ListMemberAction">

     <propertyname="memberService"ref="MemberService"></property>

   </bean>

   <!-- service -->

   <beanname="MemberService"class="service.impl.MemberServiceImpl">

     <propertyname="memberDao"ref="Member"></property>

   </bean>

   <!-- dao -->

   <beanname="Member"class="dao.impl.MemberDaoImpl">

      <propertyname="sessionFactory"ref="sessionFactory"></property>

   </bean>

11Web.xml文件配置:

<!-- 配置过滤器-->

  <filter>

    <filter-name>struts2</filter-name>

    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

  </filter>

  <filter-mapping>

    <filter-name>struts2</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

  <!-- 配置hibernate过滤器 -->

  <filter>

     <filter-name>hibernatesession</filter-name>

     <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>

   </filter>

  <filter-mapping>

     <filter-name>hibernatesession</filter-name>

     <url-pattern>/*</url-pattern>

  </filter-mapping>

  <!-- 配置spring的监听器 -->

  <listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  </listener>

  <!--spring配置文件路径 -->

  <context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:spring.xml</param-value>

  </context-param>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值