我爱Java系列---【分页查询】
一、需求
查询每个分类下的商品详情
二、实现步骤
- 菜单页面拼接超链接,传递商品分类主键
- 分类商品页面接收分类主键数据,向服务器发送AJAX请求
- Servlet接收客户端分类主键的数据
- 调用业务层方法组装PageBean数据
- 业务层调用持久层方法,分页查询数据表
- Servlet接收业务层返回的PageBean数据,转成JSON响应客户端
三、代码如下
用到的jquery工具,用的时候封装成jquery-heima-0.0.1.js,并引入当前页面,可以直接HM.ajax(url,data,function(vo){})
$.ajaxSetup({ type:"post", /*xhrFields: { withCredentials: true },*/ error:function (xhr, textStatus, errorThrown) { if(xhr.status==0){ console.log("亲,请检查后台服务器是否启动...手动滑稽") } if(xhr.status==404){ console.log("亲,请检查请求地址是否正确...手动滑稽") } if(xhr.status==405){ console.log("亲,请检查你是否实现了doPost方法...手动滑稽") } } }) var HM= { CTX:"http://api.itheima349.com", getParameter:function(name){ var pvalues=this.getParameterValues(name); return pvalues==null?null:pvalues[0]; }, getParameterValues:function(name){ return this.getParameterMap()[name]; }, getParameterMap:function(){ var url = location.search; var HMRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&"); for(var i = 0; i < strs.length; i ++) { var pname=strs[i].split("=")[0]; var pvalue=unescape(strs[i].split("=")[1]); var pvalues=null; if(HMRequest[pname]==null){ HMRequest[pname]=new Array(pvalue) }else{ HMRequest[pname].push(pvalue); } } } return HMRequest; }, isLogin:function(){ return this.cookie("JSESSIONID")==null?false:true; }, cookie:function (name) { return this.cookies()[name]; }, cookieValue:function(name){ var cookie=this.cookie(name); if(cookie==null){ return null; }else{ return cookie.value; } }, cookies:function () { var cookiesStr = document.cookie ? document.cookie.split('; ') : []; var cookies={}; for (var i = 0; i < cookiesStr.length; i++) { var parts = cookiesStr[i].split('='); var cookie = { "name":parts[0], "value":decodeURIComponent(parts[1]) }; cookies[parts[0]]=cookie; } return cookies; }, ajax:function(url,parameter,fn){ $.ajax({ url:this.CTX+url, type:"post", dataType:"json", data:parameter, xhrFields: { //允许接受从服务器端返回的cookie信息 ,默认值为false 也就是说如果必须设置为true的时候 才可以接受cookie 并且请求带上 withCredentials: true }, success:function (vo,status,xhr) { /*if(vo.code==2){ console.log("请检查请求方法是否存在"); return; } if(vo.code==3){ console.log("请检查您的服务端控制错误日志"); return; }*/ //处理登录的filter if(true){ fn(vo,status,xhr); } } }) }, ajaxFile:function(url,formId,fn){ var formData = new FormData($("#"+formId)[0]); $.ajax({ type: 'post', url:this.CTX+url, dataType:'text', data:formData, contentType:false, processData:false, success:function(data,status,xhr){ //处理登录的filter if(true){ fn(data,status,xhr); } } }) }, page:function(pb,url){ if(url.indexOf("?") != -1){ //带参数 }else{ //不带参数 url+="?_t="+new Date().getTime(); } var pageHTML=""; if(pb.pageNumber==1){ pageHTML+="<li class=\"disabled\"><a href=\"javascript:;\" aria-label=\"Previous\"><span aria-hidden=\"true\">«</span></a></li>\n"; }else{ pageHTML+="<li ><a href=\""+url+"&pageNumber="+(pb.pageNumber-1)+"\" aria-label=\"Previous\"><span aria-hidden=\"true\">«</span></a></li>\n"; } for(var i=pb.start;i<=pb.end;i++){ if(i==pb.pageNumber){ pageHTML+="<li class='active'><a href='javascript:;' >"+i+"</a></li>" }else{ pageHTML+="<li ><a href='"+url+"&pageNumber="+i+"'>"+i+"</a></li>" } } if(pb.pageNumber==pb.totalPage){ pageHTML+="<li class=\"disabled\" ><a href=\"javascript:;\" aria-label=\"Next\"><span aria-hidden=\"true\">»</span></a></li>" }else{ pageHTML+="<li><a href='"+url+"&pageNumber="+(pb.pageNumber+1)+"' aria-label=\"Next\"><span aria-hidden=\"true\">»</span></a></li>" } return pageHTML; }, time2str:function(t){ var date=new Date(t); return ""+date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate()+" "+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds(); } }
JAVA中用到的PageBean类
package com.itheima.domain; import java.util.List; public class PageBean<T> { private List<T> data; private int total; private int pageSize; private int totalPage; private int pageNumber; private int start; private int end; private int showNum=10; public int getShowNum() { return showNum; } public void setShowNum(int showNum) { this.showNum = showNum; } public List<T> getData() { return data; } public void setData(List<T> data) { this.data = data; } public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getTotalPage() { return (int) Math.ceil(total*1.0/pageSize); } public int getPageNumber() { return pageNumber; } public void setPageNumber(int pageNumber) { this.pageNumber = pageNumber; } public int getStart() { return getRange()[0]; } public int getEnd() { return getRange()[1]; } private int[] getRange(){ totalPage=getTotalPage(); //开始计算前后可以留几个 //如果为奇数 7 3-3 //如果为偶数 8 4-3 int pre=showNum%2==0?showNum/2:showNum/2; int suf=showNum%2==0?showNum/2-1:showNum/2; //计算前后的满足情况 //前后的个数已定 //前后都满足的情况 if(totalPage-pageNumber>=suf&&pageNumber-1>=pre){ start=pageNumber-pre; end=pageNumber+suf; return new int[]{start,end}; } //前面不满足的情况 if(pageNumber-1<pre&&totalPage-pageNumber>=suf){ start=1; //前面缺失的个数 int preNum=pre-pageNumber+1; end=pageNumber+suf+preNum>totalPage?totalPage:pageNumber+suf+preNum; return new int[]{start,end}; } //后面的不满足 if(totalPage-pageNumber<suf&&pageNumber-1>=pre){ end=totalPage; //后面缺失的个数 int sufNum=pageNumber+suf-totalPage; start=pageNumber-pre-sufNum<1?1:pageNumber-pre-sufNum; return new int[]{start,end}; } //都不满足 if(totalPage-pageNumber<suf&&pageNumber-1<pre){ return new int[]{1,totalPage}; } return new int[]{1,1}; } }
header页面添加连接
HM.ajax("/category?method=findAll","",function(data){ var str = "" var cateData = data.obj; $(cateData).each(function(i,element){ str= "<li><a href=\"http://www.itheima326.com:8020/web/view/product/list.html? cid=" +element.cid+"\">" +element.cname+"</a></li>" $("#cate_list").append(str); });
list 商品分页展示页面
$(function(){ //获取菜单传递的商品分类主键数据集 var cid = HM.getParameter("cid"); //获取当前的页数 var currentNumber = HM.getParameter("currentNumber"); if(currentNumber==null){ //默认第一页 currentNumber=1; } var param = "cid="+cid+"¤tNumber="+currentNumber; HM.ajax("/product?method=findByPage",param,function(data){ //取出返回pagebean的数据 //取出商品数据 var products = data.obj.list; $.each(products, function(i,element) { var s = "<div class=\"col-md-2\" style=\"text-align:center;height:200px;padding:10px 0px;\">\n" + "\t\t\t\t\t\t<a href=\"http://www.itheima326.com:8020/web/view/product/info.html?pid="+element.pid+"\">\n" + "\t\t\t\t\t\t\t<img src=\"http://www.itheima326.com:8020/web/"+element.pimage+"\" width=\"130\" height=\"130\" style=\"display: inline-block;\">\n" + "\t\t\t\t\t\t</a>\n" + "\t\t\t\t\t\t<p><a href=\"http://www.itheima326.com:8020/web/view/product/info.html?pid="+element.pid+"\" style='color:#666'>"+element.pname+"</a></p>\n" + "\t\t\t\t\t\t<p><font color=\"#E4393C\" style=\"fontsize:16px\">¥"+element.shop_price+"</font></p>\n" + "\t\t\t\t\t</div>"; $("#products").append(s); }); var pb=data.obj; //拼接分页字符串 ProductServlet var page = ""; //判断第一页 if(pb.currentNumber==1){ page+="<li class='disabled'><a href='javascript:;' aria-label='Previous'><span ariahidden='true'>«</span></a></li>"; }else{ page+="<li><a href='http://www.itheima326.com:8020/web/view/product/list.html? cid="+cid+"¤tNumber="+(pb.currentNumber-1)+"' aria-label='Previous'><span ariahidden='true'>«</span></a></li>"; } //拼接页码 for(var i=1;i<=pb.totalPage;i++){ //判断当前页 if(i==pb.currentNumber){ page+="<li class='active'><a href='javascript:;'>"+i+"</a></li>"; }else{ page+="<li><a href='http://www.itheima326.com:8020/web/view/product/list.html? cid="+cid+"¤tNumber="+i+"'>"+i+"</a></li>"; } } //判断最后一页 if(pb.currentNumber==pb.totalPage){ page+="<li class='disabled'><a href='javascript:;' aria-label='Next'><span ariahidden='true'>»</span></a></li>"; }else{ page+="<li><a href='http://www.itheima326.com:8020/web/view/product/list.html? cid="+cid+"¤tNumber="+(pb.currentNumber+1)+"' aria-label='Next'><span ariahidden='true'>»</span></a></li>"; } $("#page").html(page); }); })
ProductServlet
/** * 根据商品分类信息 * 分页查询数据 * 封装PageBean对象 */ public void findByPage(HttpServletRequest request,HttpServletResponse response)throws IOException{ //获取分类主键 String cid = request.getParameter("cid"); //获取当前页数 int currentNumber = Integer.parseInt(request.getParameter("currentNumber")); //定义每页显示条数10 int pageSize = 10; ProductService ProductDao //调用业务层方法,获取PageBean PageBean<Product> pageBean = service.findByPage(cid, currentNumber, pageSize); Result re = new Result(pageBean); response.getWriter().print(JSONObject.fromObject(re)); }
ProductService
/** * 接收分类id * 当前页数和每页条数 * 查询数据表,封装PageBean对象 */ public PageBean<Product> findByPage(String cid,int currentNumber,int pageSize){ //分页查询数据表,返回集合 List<Product> productList = productDao.findByPage(cid, currentNumber, pageSize); //查询分类商品总数 int totalCount =(int) productDao.getTotalCount(cid); //封装PageBean对象 PageBean<Product> pageBean = new PageBean<Product>(); //当前页数 pageBean.setCurrentNumber(currentNumber); //总条数 pageBean.setTotalCount(totalCount); //每页个数 pageBean.setPageSize(pageSize); //计算总页数 int totalPage = (int)Math.ceil(totalCount/pageSize*1.0); pageBean.setTotalPage(totalPage); //存储商品数据 pageBean.setList(productList); return pageBean; }
ProductDao
/** * 查询该分类下的所有商品的总数 * 传递参数,分类id */ public long getTotalCount(String cid){ String sql = "select count(*) from product where cid=?"; return template.queryForObject(sql,Long.class,cid); } /** * 分页查询商品数据 * 传递参数,分类id * 当前页数,每页显示的条数 */ public List<Product> findByPage(String pid,int currentNumber,int pageSize){ String sql = "select * from product where cid=? limit ?,?"; return template.query(sql,new BeanPropertyRowMapper<Product>(Product.class), pid,(currentNumber-1)*pageSize,pageSize); }
Redis优化菜单查询
菜单对于一个网站系统,基本上变化非常小,每次用户访问都去读取数据库效率很低,也浪费资源.将菜单存储在redis
数据库中,每次用户访问只要从内存数据库中读取菜单即可.
public List<Category> findAll(){ //先查询redis数据库 //如果不存在,查询MySQL数据库,存储到redis中,再返回 Jedis jedis = JedisUtils.getConnection(); String category = jedis.get("category"); if(category==null){ List<Category> categoryList = categoryDao.findAll(); jedis.set("category", JSONArray.fromObject(categoryList).toString()); return categoryList; }else{ JSONArray jsonObject = JSONArray.fromObject(category); List<Category> list = JSONArray.toList(jsonObject,Category.class); return list; } }
愿你走出半生,归来仍是少年!