说明:
主要技术:使用 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 >
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 >
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相关的处理语句并不懂。