继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

案例:商品浏览记录的实现

筱爻
关注TA
已关注
手记 3
粉丝 2
获赞 5

说明:
主要技术:使用 cookie 实现商品浏览记录;
项目模型:采用Model 1 (jsp + JavaBean);
步骤:
(1)DBHelper类实现数据库的连接操作;
(2)实体类;数据库表的映射
(3)业务逻辑类;DAO
(4)创建页面;

一、连接数据库:
(1)在WEB-INF的lib下导入jar包;
(2)DBHelper类
package com.mall.utils;
import java.sql.Connection;
import java.sql.DriverManager;
public class DBHelper {

private static final String driver="com.mysql.jdbc.driver";//数据库驱动; 
//连接数据库的url地址
private static final String url="jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=UTF-8"; 
private static final String username="root"; //数据库用户名
private static final String password="root"; //数据库密码
private static Connection conn=null;//数据库连接对象

//静态代码块负责加载驱动;
static {
    try {
        Class.forName(driver);
    }catch(Exception ex){
        ex.printStackTrace();
    }

}
// 单例模式返回数据库连接对象
public static Connection getConnnection() throws Exception{
    // TODO Auto-generated method stub
    if (conn==null) {
        conn = DriverManager.getConnection(url,username,password);
        return conn;
    }
    return conn;
}
//连接测试:
public static void main(String[] args) {
    try {
        Connection conn = DBHelper.getConnnection();
        if (conn != null) {
            System.out.println("数据库连接成功!");
        }else {
            System.out.println("数据库连接异常!");
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}
二、创建数据库表:
items表:商品信息表
图片描述

三、目录结构及源代码:
图片描述

创建实体类:Goods.java;
package com.mall.beans;
//商品类
public class Goods {
private int id;
private String name;
private String city;//产地
private int price;
private int number;//库存
private String picture;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
}

业务逻辑类:GoodsDao.java;
package com.mall.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import com.mall.beans.Goods;
import com.mall.utils.DBHelper;

public class GoodsDao {
//获得所有商品信息
public ArrayList<Goods> getAllGoods(){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
//商品集合
ArrayList<Goods> goodsList = new ArrayList<Goods>();
try {
conn = DBHelper.getConnnection();
String sql = "select * from goods;";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while(rs.next()) {
Goods goods = new Goods();
goods.setId(rs.getInt("id"));
goods.setName(rs.getString("name"));
goods.setCity(rs.getString("city"));
goods.setNumber(rs.getInt("number"));
goods.setPrice(rs.getInt("price"));
goods.setPicture(rs.getString("picture"));
goodsList.add(goods);
}
return goodsList;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} finally {
//释放数据集对象
if(rs != null) {
try {
rs.close();
rs = null;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//释放语句对象
if(stmt != null) {
try {
stmt.close();
stmt = null;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

    }
}
//根据商品编号获得商品资料;
public Goods getGoodsById(int id) {
    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;
    try {
        conn = DBHelper.getConnnection();
        String sql = "select * from goods where id=?;";
        stmt = conn.prepareStatement(sql);
        stmt.setInt(1, id);
        rs = stmt.executeQuery();
        if(rs.next()) {
            Goods goods = new Goods();
            goods.setId(rs.getInt("id"));
            goods.setName(rs.getString("name"));
            goods.setCity(rs.getString("city"));
            goods.setNumber(rs.getInt("number"));
            goods.setPrice(rs.getInt("price"));
            goods.setPicture(rs.getString("picture"));
            return goods;
        }else {
            return null;
        }

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;
    } finally {
        //释放数据集对象
        if(rs != null) {
            try {
                rs.close();
                rs = null;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //释放语句对象
        if(stmt != null) {
            try {
                stmt.close();
                stmt = null;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}
//使用cookie保存浏览记录;
public ArrayList<Goods> getViewList(String list){
    ArrayList<Goods> goodsList = new ArrayList<Goods>();
    int iCount=5;   //每次返回前5条;
    if(list != null && list.length()>0) {
        String[] arr = list.split("#");
        //如果商品记录大于等于"iCount"条,倒叙输出最后"iCount"条;
        if(arr.length>=iCount) {
            for(int i = arr.length-1;i>=arr.length-iCount;i--) {
                goodsList.add(getGoodsById(Integer.parseInt(arr[i])));
            }
        }
        else {//否则直接倒叙输出;
            for(int i = arr.length-1;i>=0;i--) {
                goodsList.add(getGoodsById(Integer.parseInt(arr[i])));
            }
        }

// for(String s:arr) {
// int id = Integer.parseInt(s);
// goodsList.add(getGoodsById(id));
// }
return goodsList;
}
else {
return null;
}

}

}

商品展示页面:index.jsp;
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="com.mall.dao.GoodsDao" %>
<%@ page import="com.mall.beans.Goods" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style >

allGoods{
    padding-left:10%;
}
.goods{
    width:20%;
    text-align:center;
    border-style:solid;
    border-width:2px;
    float:left;
    margin-right:2%;
}

</style>
<title>商品展示</title>
</head>
<body>
<h2>商品展示</h2>
<hr>

<!-- 商品循环展示 -->
<div id="allGoods">
<%
    GoodsDao goodsDao = new GoodsDao();
    ArrayList<Goods> list = goodsDao.getAllGoods(); 
    if(list != null && list.size()>0){
        for(int i = 0; i < list.size() ; i++){
            Goods goods = list.get(i);
%>
    <div class="goods">
        <a href="goods_details.jsp?id=<%= goods.getId()%>"><img
            src="img/goods/<%=goods.getPicture()%>" width="120" height="90"></a>
        <p class="goods_name"><%=goods.getName()%></p>
        <span class="goods_price">价格:<%=goods.getPrice()%>¥
        </span>
        <p class="goods_city">
            产地:<%=goods.getCity()%></p>
    </div>

    <%      }%>
</div>
<%  }%>

</body>
</html>
商品展示页面:goods_details.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="com.mall.dao.GoodsDao" %>
<%@ page import="com.mall.beans.Goods" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style >

goods_details{
    float:left;
    width:60%;
    text-align:center;
    border-style:solid;
    border-width:2px;
    margin:0 10%;

}
#viewList{
    float:left;
    width:15%;
    margin-right:2%;
}
.goods{
    width:100%;
    text-align:center;
    border-style:solid;
    border-color:#ccc;
    border-width:2px;
    padding:2% 10%;
    margin-bottom:3%
}

</style>
<title>商品详情页</title>
</head>
<body>
<h2>商品详情</h2>
<hr>
<div id="goods_details">
<%
GoodsDao goodsDao = new GoodsDao();

    Goods goods = goodsDao.getGoodsById(Integer.parseInt(request.getParameter("id")));

    if(goods != null){
%>
        <img src="img/goods/<%=goods.getPicture()%>" width="120" height="90">
        <p class="goods_name"><%=goods.getName()%></p>
        <span class="goods_price">价格:<%=goods.getPrice()%>¥
        </span>
        <p class="goods_city">
            产地:<%=goods.getCity()%></p>
        <p class="goods_number">
            库存:<%=goods.getNumber()%></p>
<%      
    }
%>
</div>
<%
    String list="";
    //从客户端获取Cookies集合
    Cookie[] cookies = request.getCookies();
    System.out.println("cookies="+Arrays.asList(cookies).get(1).toString());
    //遍历集合
    if(cookies != null && cookies.length>0){
        for(Cookie c : cookies){
            //如果有数据则添加到list中,并用“,”分割开;
            if(c.getName().equals("ListViewCookie")){

                list = c.getValue();
            }
        }
    }

    /* 解决了浏览记录中的商品重复问题 */
    String addId = request.getParameter("id")+"#";
    if(list.contains(addId)){
        list = list.replace(addId,"");
    }
    list += addId;
    //如果浏览记录过多则清零
    String[] arr = list.split("#");
    if(arr != null && arr.length > 0){
        if(arr.length>=1000){//这里设定记录超过1000则清零;
            list="";
        }
    }
    //将遍历的 数据添加致cookie中
    Cookie cookie = new Cookie("ListViewCookie",list);
    response.addCookie(cookie);
%>  

<div id="viewList">
<h4>浏览记录(只显示最近5条)</h4>
<!-- 循环输出浏览记录 -->
<%
    ArrayList<Goods> goodsList = goodsDao.getViewList(list);
    if(goodsList != null && goodsList.size()>0){
        for(Goods view : goodsList){
%>
    <div class="goods">
        <a href="goods_details.jsp?id=<%=view.getId() %>"><img
            src="img/goods/<%=view.getPicture()%>" width="120" height="90"></a>
        <p class="goods_name"><%=view.getName()%></p>
        <span class="goods_price">价格:<%=view.getPrice()%>¥
        </span>
        <p class="goods_city">
            产地:<%=view.getCity()%></p>
    </div>

<%  
        }
    }
%>
</div>

</body>
</html>
四、浏览记录的实现
逻辑:
图片描述
总结1:项目过程中,遇到的问题:
(1)数据库连接出问题,数据库驱动包的版本问题;
(2)使用“,” 分割时出现异常:
解决:可能是jdk版本问题,将逗号改成“#”,即可;
(3)浏览记录重复:
解决:将id加入list前,判断是否有list;(参考别人的方案,不是太理解)
详细的参看上面代码;
(4)ListViewCookie 不知道从哪里来?
回答:应该去回顾下Cookie的知识了。
这是自定义的一个键名,后面通过ListViewCookie取得它的值list。
我的疑问:为什么前面都使用了,后面才定义?
不太理解中间写的业务逻辑呀。
总结2:自身知识的缺陷:
(1)单例模式;
(2)异常处理;
(3)写业务逻辑时,强制类型转换;
判断和循环语句很重要,尤其是ArrayList,List,数组等很重要;
resquest 和 response 的运用;
还有下面的SQL相关的处理语句并不懂。
图片描述

打开App,阅读手记
2人推荐
发表评论
随时随地看视频慕课网APP