一、需求
查询每个分类下的商品详情
二、实现步骤
- 菜单页面拼接超链接,传递商品分类主键
- 分类商品页面接收分类主键数据,向服务器发送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;
}
}