使用session对购物车的简单实现(oracle数据库+数据源)

实现购物车,有很多的方法,我这次用的session,使用oracle数据库来存取数据

1、数据库设计(就一个表:商品表 items),并插入几条测试数据


2、利用MVC的思想来设计整个项目的结构,如下所示


3、首先设计po包,主要有:Items.java  Cart.java

package cn.hpe.po;


/**
 * 商品实体类
 * @author CCQ
 * @date 2016年9月17日
 */
public class Items {
	private String pid; //商品编号
	private String pname;//商品名称
	private String city;//产地
	private double price;//价格
	private int pnum;//库存
	private String pic;//商品图片
	
	//保留此不带参数的构造方法
	public Items(){
		
	}
	
	//带参数的构造方法
	public Items(String pid, String pname, String city, double price, int pnum,
			String pic) {
		this.pid = pid;
		this.pname = pname;
		this.city = city;
		this.price = price;
		this.pnum = pnum;
		this.pic = pic;
	}
	public String getPid() {
		return pid;
	}
	public void setPid(String pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public int getPnum() {
		return pnum;
	}
	public void setPnum(int pnum) {
		this.pnum = pnum;
	}
	public String getPic() {
		return pic;
	}
	public void setPic(String pic) {
		this.pic = pic;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((pid == null) ? 0 : pid.hashCode());
		result = prime * result + ((pname == null) ? 0 : pname.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Items))
			return false;
		Items other = (Items) obj;
		if (pid == null) {
			if (other.pid != null)
				return false;
		} else if (!pid.equals(other.pid))
			return false;
		if (pname == null) {
			if (other.pname != null)
				return false;
		} else if (!pname.equals(other.pname))
			return false;
		return true;
	}
}
package cn.hpe.po;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 购物车实体(添加、删除和计算价格)
 * 
 * @author CCQ
 * @date 2016年9月17日
 */
public class Cart {
	private HashMap<Items, Integer> goods; // 购买的商品集合
	private double totalPrice; // 购物车的总金额

	// 构造方法
	public Cart() {
		goods = new HashMap<Items, Integer>();
		totalPrice = 0;
	}

	public HashMap<Items, Integer> getGoods() {
		return goods;
	}

	public void setGoods(HashMap<Items, Integer> goods) {
		this.goods = goods;
	}

	public double getTotalPrice() {
		return totalPrice;
	}

	public void setTotalPrice(double totalPrice) {
		this.totalPrice = totalPrice;
	}

	// 添加商品进购物车的方法
	public boolean addGoodsInCart(Items item, int number) {
		if (goods.containsKey(item)) {
			goods.put(item, goods.get(item) + number);
		} else {
			goods.put(item, number);
		}
		calTotalPrice(); // 重新计算购物车的总金额
		return true;
	}

	// 统计购物车的总金额
	public double calTotalPrice() {
		double sum = 0;
		Set<Items> keys = goods.keySet(); // 获得键的集合
		Iterator<Items> it = keys.iterator(); // 获得迭代器的对象
		while (it.hasNext()) {
			Items i = it.next();
			sum += i.getPrice() * goods.get(i);
		}
		this.setTotalPrice(sum); // 设置购物车的总金额
		return this.getTotalPrice();
	}

	// 删除商品的方法
	public boolean removeGoodsFromCart(Items item) {
		goods.remove(item);
		calTotalPrice();// 重新计算购物车总金额
		return true;
	}
	//测试购物车的添加和计算总的金额
	public static void main(String[] args) {

		// 先创建两个商品对象
		Items i1 = new Items("1", "沃特篮球鞋", "温州", 200, 500, "001.jpg");
		Items i2 = new Items("2", "李宁运动鞋", "广州", 300, 500, "002.jpg");
		Items i3 = new Items("1", "沃特篮球鞋", "温州", 200, 500, "001.jpg");

		Cart c = new Cart();
		c.addGoodsInCart(i1, 1);
		c.addGoodsInCart(i2, 2);
		// 再次购买沃特篮球鞋,购买3双
		c.addGoodsInCart(i3, 3);

		// 变量购物商品的集合
		Set<Map.Entry<Items, Integer>> items = c.getGoods().entrySet();
		for (Map.Entry<Items, Integer> obj : items) {
			System.out.println(obj);
		}
		
		Set<Items> keys = c.getGoods().keySet(); // 获得键的集合
		Iterator<Items> it = keys.iterator(); // 获得迭代器的对象
		while (it.hasNext()) {
			Items i = it.next();
			System.out.println(i.getPname()+"=="+c.getGoods().get(i));
		}

		System.out.println("购物车的总金额:" + c.getTotalPrice());

	}
}
其中购物车类中需要注意的是:在写购物车的无参构造方法时,先初始化goods和total=0,这是很重要的,

然后有添加到购物车的方法(addGoodsInCart(Items item, int number))

把物品从购物车中移除方法(removeGoodsFromCart(Items item))

计算购物车总的金额方法(calTotalPrice())

其中在向购物车中添加商品时,用到了containsKey()方法,其本质是比较hashCode是否相等,所以在Items中必须重写equals和hashCode方法

4、编写数据访问层dao:主要是对商品的处理IItemsDao()接口和它的实现类ItemsDaoImpl()

package cn.hpe.dao.interfaces;

import java.util.List;

import cn.hpe.po.Items;

public interface IItemsDao {
	/**
	 * 查询所有的商品
	 * @return
	 * @throws Exception 
	 */
	public List<Items> getAllItems() throws Exception;
	/**
	 * 根据商品id查询商品
	 * @param pid
	 * @return
	 * @throws Exception
	 */
	public Items getItemById(String pid) throws Exception;
}

package cn.hpe.dao.impl;

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

import cn.hpe.dao.config.BaseDao;
import cn.hpe.dao.interfaces.IItemsDao;
import cn.hpe.po.Items;

/**
 * 商品操作实现类
 * @author CCQ
 * @date 2016年9月17日
 */
public class ItemsDaoImpl implements IItemsDao {

	@Override
	public List<Items> getAllItems() throws Exception {
		// TODO Auto-generated method stub
		List<Items> items = null;
		BaseDao baseDao = new BaseDao();
		try{
			Connection conn = baseDao.getConnection();
			String sql = "select * from items";
			PreparedStatement ps = conn.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			items = new ArrayList<Items>();
			while(rs.next()){
				Items item = new Items();
				item.setPid(rs.getString("pid"));
				item.setPname(rs.getString("pname"));
				item.setCity(rs.getString("city"));
				item.setPnum(rs.getInt("pnum"));
				item.setPrice(rs.getDouble("price"));
				item.setPic(rs.getString("pic"));
				items.add(item);
			}
			baseDao.closeConn(rs, ps, conn);
		}catch(Exception e){
			throw new Exception(e);
		}
		return items;
	}

	@Override
	public Items getItemById(String pid) throws Exception {
		// TODO Auto-generated method stub
		Items item = null;
		BaseDao baseDao = new BaseDao();
		try{
			Connection conn = baseDao.getConnection();
			String sql = "select * from items where pid = ?";
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setObject(1, pid);
			ResultSet rs = ps.executeQuery();
			if(rs.next()){
				item = new Items();
				item.setPid(rs.getString("pid"));
				item.setPname(rs.getString("pname"));
				item.setCity(rs.getString("city"));
				item.setPnum(rs.getInt("pnum"));
				item.setPrice(rs.getDouble("price"));
				item.setPic(rs.getString("pic"));
			}
			baseDao.closeConn(rs, ps, conn);
		}catch(Exception e){
			throw new Exception(e);
		}
		return item;
	}

}

还有就是baseDao,其中使用数据源实现和数据库的链接,需要在tomcat中配置一下数据源

package cn.hpe.dao.config;

import java.sql.*;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

/**
 * 连接oracle数据库类,使用连接池的方法
 * 
 * @author CCQ
 * 
 */
public class BaseDao {
	public Connection getConnection() throws Exception {
		System.out.println("开始使用连接池...");
		Connection conn = null;
		try {
			Context context = new InitialContext();
			DataSource ds = (DataSource) context
					.lookup("java:comp/env/jdbc/gm");
			conn = ds.getConnection();

		} catch (Exception e) {
			throw new Exception(e);
		}
		return conn;
	}

	/**
	 * 关闭数据库连接
	 */
	public void closeConn(ResultSet rs, PreparedStatement ps, Connection conn)
			throws Exception {
		try {
			if (rs != null) {
				rs.close();
			}
			if (ps != null) {
				ps.close();
			}
			if (conn != null) {
				conn.close();
			}

		} catch (Exception ex) {
			throw new Exception(ex);
		}
	}

}
在tomcat中的配置:

<Resource name="jdbc/gm" 
    	auth="Container" type="javax.sql.DataSource" maxActive="100"
    	maxIdle="30" maxWait="10000" username="gm" password="123456"
    	driverClassName="oracle.jdbc.driver.OracleDriver"
    	url="jdbc:oracle:thin:@localhost:1521:orcl"
/>

5、在书写services包,注意异常向外抛,最后在servlet中在进行处理

package cn.hpe.services.interfaces;

import java.util.List;

import cn.hpe.po.Items;

public interface IItemsService {
	/**
	 * 查询所有的商品
	 * @return
	 * @throws Exception 
	 */
	public List<Items> getAllItems() throws Exception;
	/**
	 * 根据商品id查询商品
	 * @param pid
	 * @return
	 * @throws Exception
	 */
	public Items getItemById(String pid) throws Exception;
}


package cn.hpe.services.impl;

import java.util.List;

import cn.hpe.dao.impl.ItemsDaoImpl;
import cn.hpe.dao.interfaces.IItemsDao;
import cn.hpe.po.Items;
import cn.hpe.services.interfaces.IItemsService;

public class ItemsServiceImpl implements IItemsService{

	@Override
	public List<Items> getAllItems() throws Exception {
		// TODO Auto-generated method stub
		IItemsDao itemsDao = new ItemsDaoImpl();
		List<Items> items = null;
		try{
			items = itemsDao.getAllItems();
		}catch(Exception e){
			throw new Exception(e);
		}
		return items;
	}

	@Override
	public Items getItemById(String pid) throws Exception {
		// TODO Auto-generated method stub
		IItemsDao itemsDao = new ItemsDaoImpl();
		Items item = null;
		try{
			item = itemsDao.getItemById(pid);
		}catch(Exception e){
			throw new Exception(e);
		}
		return item;
	}

}

6、数据控制层:servlet的书写,主要有商品控制:ItemsServlet和CartServlet

package cn.hpe.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hpe.po.Items;
import cn.hpe.services.impl.ItemsServiceImpl;
import cn.hpe.services.interfaces.IItemsService;

public class ItemsServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	IItemsService itemsService = new ItemsServiceImpl();

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		this.doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		String op = request.getParameter("option");
		if ("list".equals(op)) {
			itemList(request, response);
		}
		if ("item".equals(op)) {
			itemDetails(request, response);
		}
	}

	// 显示所有的商品
	public void itemList(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		try {
			List<Items> items = new ArrayList<Items>();
			items = itemsService.getAllItems();
			request.setAttribute("items", items);
			request.getRequestDispatcher("index.jsp")
					.forward(request, response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 显示商品的详细信息
	public void itemDetails(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		try {
			String pid = request.getParameter("pid");
			Items item = new Items();
			item = itemsService.getItemById(pid);
			request.setAttribute("item", item);
			request.getRequestDispatcher("details.jsp")
					.forward(request, response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

package cn.hpe.action;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hpe.po.Cart;
import cn.hpe.po.Items;
import cn.hpe.services.impl.ItemsServiceImpl;
import cn.hpe.services.interfaces.IItemsService;

/**
 * 购物车的Servlet
 * 
 * @author CCQ
 * @date 2016年9月17日
 */
public class CartServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	IItemsService itemsService = new ItemsServiceImpl();

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		this.doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		String op = request.getParameter("option");
		if ("add".equals(op)) {
			addToCart(request, response);
			String pid = request.getParameter("pid");
			response.sendRedirect("ItemsServlet?pid="+pid+"&option=item");
		} else if ("show".equals(op)) {
			cartList(request, response);
		} else if ("delete".equals(op)) {
			deleteFromCart(request, response);
			request.getRequestDispatcher("CartServlet?option=show").forward(request, response);
		}

	}

	// 添加商品进购物车
	public boolean addToCart(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		try {
			String pid = request.getParameter("pid");
			int num = Integer.parseInt(request.getParameter("num"));
			Items item = itemsService.getItemById(pid);
			// 是否是第一次给购物车添加商品时,需要给session中创建一个新的购物车对象
			if (request.getSession().getAttribute("cart") == null) {
				Cart cart = new Cart();
				request.getSession().setAttribute("cart", cart);
			}
			Cart cart = (Cart) request.getSession().getAttribute("cart");
			if (cart.addGoodsInCart(item, num)) {
				cart = (Cart) request.getSession().getAttribute("cart");
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	// 从购物车删除商品
	public boolean deleteFromCart(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		try {
			String pid = request.getParameter("pid");
			Cart cart = (Cart) request.getSession().getAttribute("cart");
			Items item = itemsService.getItemById(pid);
			if (cart.removeGoodsFromCart(item)) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	// 显示购物车
	public void cartList(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		Cart cartMap = (Cart) request.getSession().getAttribute("cart");
		request.setAttribute("cartMap", cartMap);
		request.getRequestDispatcher("cartList.jsp").forward(request, response);
	}

}

7、最后的就是前台JSP页面的设计,我的设计就是简单地排版,哈哈

(1)商品显示主页面  index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>商品展示页面</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
<style type="text/css">
div {
	float: left;
	text-align: center;
}
</style>
</head>

<body>
	<h1>商品展示</h1>
	<hr>
	<table>
		<tr>
			<td><c:forEach items="${items }" var="item">
					<div>
						<dl>
							<dd>
								<a href="ItemsServlet?option=item&pid=${item.pid}"> <img
									src="images/${item.pic }" width="120" height="90" border="1" /></a>
							</dd>
							<dd>${item.pname }</dd>
							<dd>产地:${item.city }</dd>
							<dd>价格:¥${item.price }</dd>
						</dl>
					</div>
				</c:forEach></td>
		</tr>

	</table>
</body>
</html>
(2)商品详细信息显示页面 details.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>商品详细信息页面</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
<style type="text/css">
table {
	margin: 0 auto;
}

span {
	display: inline-block;
	border: 1px solid #cccccc;
	width: 15px;
	height: 20px;
	cursor: pointer;
	text-align: center;
}

#sub {
	margin-right: -10px;
	border-right-width: 0px;
}

#add {
	margin-left: -10px;
	border-left-width: 0px;
}

#number {
	text-align: center;
}
</style>
</head>

<body>
	<h1>商品详情</h1>
	<a href="ItemsServlet?option=list">首页</a> >>
	<a href="ItemsServlet?option=list">商品列表</a>
	<hr>
	<table>
		<tr>
			<td rowspan="4"><img src="images/${item.pic }" width="200"
				height="160" /></td>
		</tr>
		<tr>
			<td>${item.pname }</td>
		</tr>
		<tr>
			<td>产地:${item.city }</td>
		</tr>
		<tr>
			<td>价格:¥${item.price }</td>
		</tr>
		<tr>
			<td>购买数量:<span id="sub" οnclick="sub()">-</span> <input
				type="text" id="number" name="number" value="1" size="2" /> <span
				id="add" οnclick="add()">+</span>
			</td>
		</tr>
		<tr>
			<td>
				<div id="cart">
					<img src="images/in_cart.png" οnclick="addCart()">
					<a href="CartServlet?option=show"> <img
						src="images/view_cart.jpg" />
					</a>
				</div>
			</td>
		</tr>
	</table>
</body>
<script type="text/javascript">
	function sub() {
		var number = parseInt(document.getElementById("number").value);
		if (number > 1) {
			document.getElementById("number").value = --number;
		}

	}
	function add() {
		var number = parseInt(document.getElementById("number").value);
		if (number < 100) {
			document.getElementById("number").value = ++number;
		}

	}
	function addCart() {
		var num = document.getElementById("number").value;
		document.location.href = "CartServlet?pid=${item.pid}&option=add&num="+num;
		
		alert("添加成功!");
	}
</script>
</html>

(3)显示购物车 cartList.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>购物车</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
<style type="text/css">
table {
	margin: 0 auto;
	text-align: center;
	margin-top: 50px;
}

td {
	height: 80px;
}

span {
	display: inline-block;
	float: right;
	margin-top: 25px;
	margin-right: 50px;
}
</style>
</head>

<body>
	<h1>我的购物车</h1>
	<a href="ItemsServlet?option=list">首页</a> >>
	<a href="ItemsServlet?option=list">商品列表</a>
	<hr />
	<table border="1px" cellpadding="0" cellspacing="0">
		<tr>
			<th>商品名称</th>
			<th>商品单价</th>
			<th>商品价格</th>
			<th>购买数量</th>
			<th>操作</th>
		</tr>
		<c:forEach items="${cartMap.goods }" var="c">
			<tr>

				<td width="300px"><img width="100px" src="images/${c.key.pic} " /><span>${c.key.pname }</span></td>
				<td width="200px">${c.key.price }元</td>
				<td width="200px">${c.key.price*c.value }元</td>
				<td width="200px">${c.value }件</td>
				<td width="200px"><a
					href="CartServlet?option=delete&pid=${c.key.pid }"
					οnclick="delcfm();"> 删除 </a></td>
			</tr>
		</c:forEach>
		<tr>
			<td colspan="5">总计:${cartMap.totalPrice}元</td>
		</tr>
	</table>
</body>
<script language="javascript">
	function delcfm() {
		if (!confirm("确认要删除?")) {
			window.event.returnValue = false;
		}
	}
</script>
</html>

8、项目运行结果展示



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值