关于Javaweb分页处理以及导航栏实现小记

对于搜索功能结果展示的分页处理,首先应该明确的是目前页,每页显示数据的条数,以及总的数据数目。

接下来,通过这些数据来计算出总的显示页数,以及数据库语句limit查询的范围。

Object result:是分页显示的数据,这里设置为Object的目的是为了方便通过JSON传输。

 public class PageBean {
     private int pageNum; // 当前页,从请求那边传过来
     private int pageSize; // 每页显示的数据条数
     private int totalRecord; //总的记录条数
     
     private int totalPage; // 总页数:totalRecord/pageSize
     private int startIndex; // 从第几行开始查数据
     
     private Object result; // JSON封装好的数据
     
     // 分页显示的页数,比如在页数上显示1,2,3,4,5.start就是1,end就是5
     private int start;
     private int end;
     
     public PageBean(int pageNum, int pageSize, int totalRecord) {
         this.pageNum = pageNum;
         this.pageSize = pageSize;
         this.totalRecord = totalRecord;
         
         // 计算总页数
         if (totalRecord % pageSize == 0) {// 总的数据正好整除每页所显示数据
             this.totalPage = totalRecord / pageSize;
         } else {
             // 不整除,页数+1
             this.totalPage = totalRecord / pageSize + 1;
         }
         
         // 数据库查询索引
         this.startIndex = (pageNum - 1) * pageSize;
         // 显示5页
         this.start = 1;
         this.end = 5;
         
         // 显示页数的算法
         if (totalPage <= 5) {// 总页数小于5页
             this.end = this.totalPage;
         } else {
             // 总页数是大于5的,那么就要根据当前是第几页来判断显示的start和end
             this.start = pageNum - 2;
             this.end = pageNum + 2;
             
             if (start <= 0) {
                 this.start = 1;
                 this.end = 5;
             }
             if (end > this.totalPage) {
                 this.end = totalPage;
                 this.start = end - 4;
             }
         }
         
     }
 
     public int getPageNum() {
         return pageNum;
     }
 
     public void setPageNum(int pageNum) {
         this.pageNum = pageNum;
     }
 
     public int getPageSize() {
         return pageSize;
     }
 
     public void setPageSize(int pageSize) {
         this.pageSize = pageSize;
     }
 
     public int getTotalRecord() {
         return totalRecord;
     }
 
     public void setTotalRecord(int totalRecord) {
         this.totalRecord = totalRecord;
     }
 
     public int getTotalPage() {
         return totalPage;
     }
 
     public void setTotalPage(int totalPage) {
         this.totalPage = totalPage;
     }
 
     public int getStartIndex() {
         return startIndex;
     }
 
     public void setStartIndex(int startIndex) {
         this.startIndex = startIndex;
     }
 
     public Object getResult() {
         return result;
     }
 
     public void setResult(Object result) {
         this.result = result;
     }
 
     public int getStart() {
         return start;
     }
 
     public void setStart(int start) {
         this.start = start;
     }
 
     public int getEnd() {
         return end;
     }
 
     public void setEnd(int end) {
         this.end = end;
     }
     
     
 }

持久层主要是得到PageBean对象里的startIndex和pageSize数据来进行limit查询

代码如下:

图片描述

图片描述

 public class SearchUtils {
     /**
      * 通过模糊匹配帖子标题查询所有帖子信息(themeId,themeTitle,createTime,userID,nickName,boardId,
      * boardNamereadCount,postCount,)
      * 
      * @param keyWord
      * @return
      */
     public static List<Object> searchByThemeTitle(String keyWord) {
         List<Object> searchResult = null;
         String sql = "select bt.themeId, bt.themeTitle,bt.createTime,bt.userID,u.nickName,bt.boardId,sb.smallBoardName,bt.readCount,bt.postCount,bt.content, bb.bigBoardName from bbs_theme bt, `user` u, smallboard sb, bigboard bb where bt.boardId = sb.smallBoardId and bt.userID = u.userID and sb.parentId=bb.bigBoardId and bt.themeTitle like '%"+keyWord+"%' order by bt.readCount DESC";
         Session session = HibernateSessionFactory.openSession();
         try {
             SQLQuery sqlQuery = session.createSQLQuery(sql);
             searchResult = sqlQuery.list();
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             session.close();
         }
         return searchResult;
     }
     
     /**
      * 分页查询
      * @param start
      * @param end
      * @param keyWord
      * @return
      */
     public static List<Object> searchByThemeTitle(int start, int end, String keyWord) {
         List<Object> searchResult = null;
         String sql = "select bt.themeId, bt.themeTitle,bt.createTime,bt.userID,u.nickName,bt.boardId,sb.smallBoardName,bt.readCount,bt.postCount,bt.content, bb.bigBoardName from bbs_theme bt, `user` u, smallboard sb, bigboard bb where bt.boardId = sb.smallBoardId and bt.userID = u.userID and sb.parentId=bb.bigBoardId and bt.themeTitle like '%"+keyWord+"%' order by bt.readCount DESC limit "+start+","+end;
         Session session = HibernateSessionFactory.openSession();
         try {
             SQLQuery sqlQuery = session.createSQLQuery(sql);
             searchResult = sqlQuery.list();
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             session.close();
         }
         return searchResult;
     }
 }

View Code
业务逻辑层主要负责创建PageBean对象并封装数据

代码如下:

 public class SearchServiceImpl implements SearchService {
     
     @Override
     public String searchByTitle(int pageNum, int pageSize, String keyWord) {
         List<Object> searchResult = SearchUtils.searchByThemeTitle(keyWord);
         // 查询的数据总数
         int totalRecord = searchResult.size();
         // 创建pageBean对象
         PageBean pb = new PageBean(pageNum, pageSize, totalRecord);
         
         // 获取查询的索引
         int startIndex = pb.getStartIndex();
         
         List<Object> searchForPageResult = SearchUtils.searchByThemeTitle(startIndex, pageSize, keyWord);
         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         for (Object obj : searchForPageResult) {
             Object[] objArray = (Object[]) obj;
             Map<String, Object> map = new HashMap<String, Object>();
             map.put("themeId", objArray[0]);
             map.put("themeTitle", objArray[1]);
             // 解决从MySQL读出的timestamp类型的数据中后面跟着.0的问题
             try {
                 Date date = sdf.parse(String.valueOf(objArray[2]));
                 String createTime = sdf.format(date);
                 map.put("createTime", createTime);
             } catch (ParseException e) {
                 e.printStackTrace();
             }
             map.put("userID", objArray[3]);
             map.put("nickName", objArray[4]);
             map.put("boardId", objArray[5]);
             map.put("smallBoardName", objArray[6]);
             map.put("readCount", objArray[7]);
             map.put("postCount", objArray[8]);
             map.put("content", objArray[9]);
             map.put("bigboardName", objArray[10]);
             list.add(map);
         }
         pb.setResult(list);
         String result = JSON.toJSONString(pb);
         return result;
     }
 
 }

关于servlet层,应该为了考虑到微信小程序端的数据传输,所以关于数据的赋值是通过JSON传输,web端通过ajax来请求,接受数据。

代码如下:

 public class SearchServlet extends HttpServlet {
 
     // 调用service
     private SearchService searchService = new SearchServiceImpl();
     // 获取输出流
     private PrintWriter out;
     
     public void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         // 设置编码
         request.setCharacterEncoding("UTF-8");
         response.setContentType("text/html;charset=utf-8");
         // 获取前端数据
         // 获取搜索的类型
 //        String type = request.getParameter("searchType");
         // 目前就先实现关于帖子标题的模糊查询
         // 获取关键词
         String kw = request.getParameter("kw");
         // 当前页,默认为1
         int pageNum = 1;
         // 每页显示的记录数
         int pageSize = 5;
         String result;
         if ("".equals(kw) || kw == null) {
             result = "";
         } else {
             String keyWord = URLDecoder.decode(kw, "UTF-8");
             if (request.getParameter("pn") == null) {// 没有pageNum,则默认为1
                 result = searchService.searchByTitle(pageNum, pageSize,keyWord);
             } else { // 获取当前页
                 pageNum = Integer.valueOf(request.getParameter("pn"));
                 result = searchService.searchByTitle(pageNum, pageSize,keyWord);
             }
         }
         response.setContentType("text/json;charset=utf-8");
         out = response.getWriter();
         out.write(result);
         out.flush();
     }
 
     
     public void doPost(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         doGet(request, response);
     }
 
 }

接下来,就是web端获取数据后如何处理?

这里通过Ajax请求数据填充网页。

代码如下:

 $(document).ready(getSearch());
 
 // 获取搜索结果
 function getSearch() {
     var url=location.search;
     var k = url.split("=", 2)[1].split("&amp;")[0];
     var kw = decodeURI(decodeURI(k));
     //console.log(url);
     //console.log(decodeURI(decodeURI(kw)));
     $.ajax({
         type: "GET",
         url: "/DaTangBBs/SearchServlet"+url,
         success: function(r) {
             console.log(r);
 //            console.log(r.result);
             var result = "结果: <em>找到&amp;nbsp;&amp;nbsp;&amp;nbsp;“<span>"+kw+"</span>”&amp;nbsp;&amp;nbsp;&amp;nbsp;相关内容"+r.totalRecord+"个</em>";
             $("#result").html(result);
             var res = r.result;
             var str = "";
             if (res.length == 0) {
                 str += "<p>对不起,没有找到匹配结果</p>";
             }
             else {
                 str += "<ul>";
                 for (var key in res) {
                     // console.log(res[key].themeTitle);
                     var content = cutstring(htmlToText(res[key].content), 80);
                     // console.log(content);
                     str += "<li class='pbw'><h3 class='xs3'>";
                     str += "<a href='/DaTangBBs/web/show.jsp?postID="+res[key].themeId+"&amp;userID="+res[key].userID+"&amp;method=read' target='_blank'>"+res[key].themeTitle+"</a>";
                     str += "</h3>";
                     str += "<p class='xg1'>"+res[key].postCount+"个回复 - "+res[key].readCount+"次查看</p>";
                     str += "<p class='content'>"+content+"</p>";
                     str += "<p><span>"+res[key].createTime+"</span> - <span>";
                     str += "<a href='/DaTangBBs/web/userInfo/user.jsp?userID="+res[key].userID+"' target='_blank'>"+res[key].nickName+"</a></span> - <span>";
                     str += "<a href='/DaTangBBs/web/plate.jsp?key="+encodeURI(encodeURI(res[key].bigboardName))+"&amp;value="+encodeURI(encodeURI(res[key].smallBoardName))+"' target='_blank' class='xi1'>"+res[key].smallBoardName+"</a></span>";
                 }
                 str += "</ul>";
                 
             }
             $("#threadlist").html(str);
             var page = "";
             if (r.start == 1) {// 从第一页开始,不显示首页
             } else {
                 page += "<a href='/DaTangBBs/web/search.html?kw="+k+"&amp;pn="+1+"'>首页</a>";
             }
             if (r.pageNum == 1) {
                 // 当前页为首页,不显示上一页
             } else {
                 page += "<a href='/DaTangBBs/web/search.html?kw="+k+"&amp;pn="+(r.pageNum-1)+"'>上一页</a>";
             }
             for (var i = r.start; i <= r.end; i++) {
                 if (i == r.pageNum) {
                     page += "<strong>"+i+"</strong>";
                 } else {
                     page += "<a href='/DaTangBBs/web/search.html?kw="+k+"&amp;pn="+i+"'>"+i+"</a>";
                 }
                 
             }
             
             if (r.pageNum == r.totalPage || r.totalPage == 0) {
                 // 当前页为尾页或者没有搜索结果,不显示下一页
             }else {
                 page += "<a href='/DaTangBBs/web/search.html?kw="+k+"&amp;pn="+(r.pageNum+1)+"'>下一页</a>";
             }
             if (r.end == r.totalPage) {
                 // 不显示尾页
             } else {
                 page += "<a href='/DaTangBBs/web/search.html?kw="+k+"&amp;pn="+r.totalPage+"'>尾页</a>";
             }
             $("#pageList").html(page);
             
         }
     });
 }
 
 // 将HTML转为文本
 function htmlToText(hcontent) {
     var content = hcontent;
     content = content.replace(/(\n)/g, "");  
     content = content.replace(/(\t)/g, "");
     content = content.replace(/(\r)/g, "");  
     content = content.replace(/<\/?[^>]*>/g, "");  // 匹配<..><../> 将其替换为""
     content = content.replace(/\s*/g, "");
     return content;
 }
 
 // 截取内容显示
 function cutstring(str, len) {
     if (str.length <= len) {
         return str;
     } else {
         str = str.substr(0,len) + "...";
         return str;
     }
 }

这里再来一小段关于分页导航栏的css样式

 // 导航栏css
 .pgs {
     
 }
 
 .mbm {
     margin-bottom: 10px !important;
 }
 
 .c1 {
     zoom:1;
 }
 
 .pg {
     float: none;
     line-height:33px;
 }
 
 .pg a, .pg strong {
     float:left;
     display:inline;
     margin-left:4px;
     padding:0 15px;
     height:33px;
     border:1px solid;
     border-color: #e4e4e4;
     background-color:#FFF;
     background-repeat:no-repeat;
     color:#555;
     overflow:hidden;
     text-decoration:none;
 }
 
 .pg strong {
     background-color:#00aa98;
     color:#FFF;
 }

最后是效果图:

图片描述

在这里,要感谢@一杯凉茶的博文。参考博文:https://www.cnblogs.com/whgk/p/6474396.html