查看原文
其他

SSM 框架!实现分页和搜索分页

点击上方 "程序员小乐"关注公众号, 星标或置顶一起成长

每天凌晨00点00分, 第一时间与你相约

每日英文

We don't need to meet again for we are just passers by.To forget is the best commemoration for each other.

很多人不需要再见,因为只是路过而已。遗忘就是我们给彼此最好的纪念。


每日掏心话

走远了再回头看,很多人已经淡忘,只有很少的人牵连着我们的幸福与快乐,这才是我们真正要珍惜的地方。


来自:在路上 | 责编:乐乐

链接:blog.csdn.net/zhshulin

程序员小乐(ID:study_tech)第 659 次推文   图片来自网络


往日回顾:你不知道的 IDEA Debug 调试小技巧!



   正文   

  

分页是Java Web项目常用的功能,昨天在Spring MVC中实现了简单的分页操作和搜索分页,在此记录一下。使用的框架为(MyBatis+SpringMVC+Spring)。

首先我们需要一个分页的工具类:


1.分页


import java.io.Serializable;  
 
/** 
* 分页 
*/
  
public class Page implements Serializable {  
 
   private static final long serialVersionUID = -3198048449643774660L;  
 
   private int pageNow = 1// 当前页数  
 
   private int pageSize = 4// 每页显示记录的条数  
 
   private int totalCount; // 总的记录条数  
 
   private int totalPageCount; // 总的页数  
 
   @SuppressWarnings("unused")  
   private int startPos; // 开始位置,从0开始  
 
   @SuppressWarnings("unused")  
   private boolean hasFirst;// 是否有首页  
 
   @SuppressWarnings("unused")  
   private boolean hasPre;// 是否有前一页  
 
   @SuppressWarnings("unused")  
   private boolean hasNext;// 是否有下一页  
 
   @SuppressWarnings("unused")  
   private boolean hasLast;// 是否有最后一页  
     
   /** 
    * 通过构造函数 传入  总记录数  和  当前页 
    * @param totalCount 
    * @param pageNow 
    */
  
   public Page(int totalCount, int pageNow) {  
       this.totalCount = totalCount;  
       this.pageNow = pageNow;  
   }  
     
   /** 
    * 取得总页数,总页数=总记录数/总页数 
    * @return 
    */
  
   public int getTotalPageCount() {  
       totalPageCount = getTotalCount() / getPageSize();  
       return (totalCount % pageSize == 0) ? totalPageCount  
               : totalPageCount + 1;  
   }  
 
   public void setTotalPageCount(int totalPageCount) {  
       this.totalPageCount = totalPageCount;  
   }  
 
   public int getPageNow() {  
       return pageNow;  
   }  
 
   public void setPageNow(int pageNow) {  
       this.pageNow = pageNow;  
   }  
 
   public int getPageSize() {  
       return pageSize;  
   }  
 
   public void setPageSize(int pageSize) {  
       this.pageSize = pageSize;  
   }  
 
   public int getTotalCount() {  
       return totalCount;  
   }  
 
   public void setTotalCount(int totalCount) {  
       this.totalCount = totalCount;  
   }  
   /** 
    * 取得选择记录的初始位置 
    * @return 
    */
  
   public int getStartPos() {  
       return (pageNow - 1) * pageSize;  
   }  
 
   public void setStartPos(int startPos) {  
       this.startPos = startPos;  
   }  
 
   /** 
    * 是否是第一页 
    * @return 
    */
  
   public boolean isHasFirst() {  
       return (pageNow == 1) ? false : true;  
   }  
 
   public void setHasFirst(boolean hasFirst) {  
       this.hasFirst = hasFirst;  
   }  
   /** 
    * 是否有首页 
    * @return 
    */
  
   public boolean isHasPre() {  
       // 如果有首页就有前一页,因为有首页就不是第一页  
       return isHasFirst() ? true : false;  
   }  
 
   public void setHasPre(boolean hasPre) {  
       this.hasPre = hasPre;  
   }  
   /** 
    * 是否有下一页 
    * @return 
    */
  
   public boolean isHasNext() {  
       // 如果有尾页就有下一页,因为有尾页表明不是最后一页  
       return isHasLast() ? true : false;  
   }  
 
   public void setHasNext(boolean hasNext) {  
       this.hasNext = hasNext;  
   }  
   /** 
    * 是否有尾页 
    * @return 
    */
  
   public boolean isHasLast() {  
       // 如果不是最后一页就有尾页  
       return (pageNow == getTotalCount()) ? false : true;  
   }  
 
   public void setHasLast(boolean hasLast) {  
       this.hasLast = hasLast;  
   }  
 
}


有了这个工具类后,首先编写MyBatis的XxxxMapper.xml配置文件中的SQL语句,如下:


<!-- 分页SQL语句 -->  
<select id="selectProductsByPage" resultMap="返回值类型">  
 select   
 *  
 from 表名 WHERE user_id = #{userId,jdbcType=INTEGER} limit #{startPos},#{pageSize}   
</select>  
<!-- 取得记录的总数 -->  
<select id="getProductsCount" resultType="long">  
 SELECT COUNT(*) FROM 表名 WHERE user_id = #{userId,jdbcType=INTEGER}   
</select>


此处我们可以看到,2个<select>需要分别传入3个和1个参数,此时在对应的DAO文件IXxxxDao中编写接口来编写对应的方法,方法名和mapper.xml中的id属性值一致:


/** 
* 使用注解方式传入多个参数,用户产品分页,通过登录用户ID查询 
* @param page 
* @param userId 
* @return startPos},#{pageSize}  
*/
  
public List<Products> selectProductsByPage(@Param(value="startPos") Integer startPos,@Param(value="pageSize") Integer pageSize,@Param(value="userId") Integer userId);  
  
/** 
* 取得产品数量信息,通过登录用户ID查询 
* @param userId 
* @return 
*/
  
public long getProductsCount(@Param(value="userId") Integer userId);


接口定义完成之后需要编写相应的业务接口和实现方法,在接口中定义这样一个方法,然后实现类中覆写一下:


/** 
    * 分页显示商品 
    * @param request 
    * @param model 
    * @param loginUserId 
    */
  
   void showProductsByPage(HttpServletRequest request,Model model,int loginUserId);


接下来实现类中的方法就是要调用DAO层和接受Controller传入的参数,进行业务逻辑的处理,request用来获取前端传入的参数,model用来向JSP页面返回处理结果。


@Override  
public void showProductsByPage(HttpServletRequest request, Model model,int loginUserId) {  
    String pageNow = request.getParameter("pageNow");  
 
   Page page = null;  
 
   List<ProductWithBLOBs> products = new ArrayList<ProductWithBLOBs>();  
 
   int totalCount = (int) productDao.getProductsCount(loginUserId);  
 
   if (pageNow != null) {  
       page = new Page(totalCount, Integer.parseInt(pageNow));  
       allProducts = this.productDao.selectProductsByPage(page.getStartPos(), page.getPageSize(), loginUserId);  
    } else {  
       page = new Page(totalCount, 1);  
       allProducts = this.productDao.selectProductsByPage(page.getStartPos(), page.getPageSize(), loginUserId);  
    }  
 
   model.addAttribute("products", products);  
   model.addAttribute("page", page);  
}


接下来是控制器的编写,当用户需要跳转到这个现实产品的页面时,就需要经过这个控制器中相应方法的处理,这个处理过程就是调用业务层的方法来完成,然后返回结果到JSP动态显示,服务器端生成好页面后传给客户端(浏览器)现实,这就是一个MVC过程。


/** 
* 初始化 “我的产品”列表 JSP页面,具有分页功能 
*  
* @param request 
* @param model 
* @return 
*/
  
@RequestMapping(value = "映射路径", method = RequestMethod.GET)  
public String showMyProduct(HttpServletRequest request, Model model) {  
   // 取得SESSION中的loginUser  
   User loginUser = (User) request.getSession().getAttribute("loginUser");  
   // 判断SESSION是否失效  
   if (loginUser == null || "".equals(loginUser)) {  
       return "redirect:/";  
   }  
 
   int loginUserId = loginUser.getUserId();  
   //此处的productService是注入的IProductService接口的对象  
   this.productService.showProductsByPage(request, model, loginUserId);  
 
   return "跳转到的JSP路径";  
}


JSP页面接受部分我就不写了,每个人都一样,也就是结合JSTL和EL来写,(在循环输出的时候也做了判断,如果接受的参数为空,那么输出暂无商品,只有接受的参数不为空的时候,才循环输出,使用<<c:when test="${}">结合<c:otherwise>),这里只给出分页的相关代码:


<!-- 分页功能 start -->  
   <div align="center">  
       <font size="2">共 ${page.totalPageCount} 页</font> <font size="2">第  
           ${page.pageNow} 页</font> <a href="myProductPage?pageNow=1">首页</a>  
        <c:choose>  
           <c:when test="${page.pageNow - 1 > 0}">  
               <a href="myProductPage?pageNow=${page.pageNow - 1}">上一页</a>  
            </c:when>  
           <c:when test="${page.pageNow - 1 <= 0}">  
               <a href="myProductPage?pageNow=1">上一页</a>  
           </c:when>  
       </c:choose>  
       <c:choose>  
           <c:when test="${page.totalPageCount==0}">  
               <a href="myProductPage?pageNow=${page.pageNow}">下一页</a>  
           </c:when>  
           <c:when test="${page.pageNow + 1 < page.totalPageCount}">  
               <a href="myProductPage?pageNow=${page.pageNow + 1}">下一页</a>  
            </c:when>  
           <c:when test="${page.pageNow + 1 >= page.totalPageCount}">  
               <a href="myProductPage?pageNow=${page.totalPageCount}">下一页</a>  
            </c:when>  
       </c:choose>  
       <c:choose>  
           <c:when test="${page.totalPageCount==0}">  
               <a href="myProductPage?pageNow=${page.pageNow}">尾页</a>  
           </c:when>  
           <c:otherwise>  
               <a href="myProductPage?pageNow=${page.totalPageCount}">尾页</a>  
            </c:otherwise>  
       </c:choose>  
   </div>  
   <!-- 分页功能 End -->


2.查询分页


关于查询分页,大致过程完全一样,只是第三个参数(上面是loginUserId)需要接受用户输入的参数,这样的话我们需要在控制器中接受用户输入的这个参数(页面中的<input>使用GET方式传参)。


然后将其加入到SESSION中,即可完成查询分页(此处由于“下一页”这中超链接的原因,使用了不同的JSP页面处理分页和搜索分页,暂时没找到在一个JSP页面中完成的方法,出现了重复代码,这里的重复代码就是输出内容的那段代码,可以单独拿出去,然后用一个<include>标签加载到需要的JSP页面就可以了,这样可以避免代码重复):


这里给出控制器的代码作为参考:


/** 
    * 通过 产品名称 查询产品 
    * @param request 
    * @param model 
    * @return 
    */
  
   @RequestMapping(value = "映射地址", method = RequestMethod.GET)  
   public String searchForProducts(HttpServletRequest request, Model model) {  
       HttpSession session = request.getSession();  
 
       String param = request.getParameter("param");  
 
       String condition = (String) session.getAttribute("condition");  
 
       //先判断SESSION中的condition是否为空  
       if (condition == null) {  
           condition = new String();  
           session.setAttribute("condition", condition);  
           //如果Session中的condition为空,再判断传入的参数是否为空,如果为空就跳转到搜索结果页面  
            if (param == null || "".equals(param)) {  
               return "private/space/ProductSearchResult";  
           }  
       }  
       //如果SESSION不为空,且传入的搜索条件param不为空,那么将param赋值给condition  
        if (param != null && !("".equals(param))) {  
           condition = param;  
           session.setAttribute("condition", condition);  
       }  
       //使用session中的condition属性值来作为查询条件  
       this.productService.showSearchedProductsByPage(request, model, condition);  
  
       return "跳转的页面";  
   }


欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。

欢迎各位读者加入程序员小乐技术群,在公众号后台回复“加群”或者“学习”即可。

猜你还想看


阿里、腾讯、百度、华为、京东最新面试题汇集

从 Spring Cloud 看一个微服务框架的「 五脏六腑 」

学界:为代码自动添加注释,让 Java 程序的阅读和开发更高效

在 JVM 眼中 .class 文件是什么样的?值得收藏!


关注微信公众号「程序员小乐」,收看更多精彩内容
嘿,你在看吗?

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存