购物车与下订单项目总结

最近跟着视频做了一个购书网站的小项目,有必要总结一下。代码中用到c3p0和BeanUtils

1.购物车

首先得根据对购物车类进行封装。经过分析,将多种物品添加到购物车中后,购物车中就不止一个购物项了,而每个购物项又有图书的信息,所以在此对购物车提取出两个类;一个是Cart类,用来存放购物项,以便将购物项放置到session中,并对购物车进行操作,而CartItem类用来封装购物项的。
Cart.java代码如下:
package cn.my.bookstore.cart;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
/***
 * 购物车类 添加到购物车,从购物车中移除,清空购物车
 * @author wulaoern
 *
 */
public class Cart {
        //存放购物项用map的好处是,可以用bid当作键值,这样方便查找。
	private Map<String ,CartItem> map=new LinkedHashMap<String, CartItem>();
	private BigDecimal total=new BigDecimal(0);  //总价
	/**
	 * 添加购物车
	 * @param carItem
	 */
	public BigDecimal getTotal()
	{
		return total;
	}
	/**
	 * 获得购物项集合
	 * @return
	 */
	public Collection<CartItem> getCartItems()
	{
		return map.values();
	}
	public void add(CartItem cartItem)
	{
		/**
		 * 先找到该数是否存在,如果存在,更新数量,不存在,添加进去购物车,同时更新总价
		 */
		String bid=cartItem.getBook().getBid();
		
		if (map.containsKey(bid)){
			//如果购物车中包含该购物项,更新数量
			//购物车中原来的购物项
			CartItem _cartItem=map.get(bid);
			//更新购物车中购物项的数量,不用担心小计,自动更新
			_cartItem.setCount(_cartItem.getCount()+cartItem.getCount());			
		}
		else
		{
			map.put(bid, cartItem);
		}
		//更新购物车总价
		total=total.add(cartItem.getSubtotal());
	
	}
	/**
	 * 从购物车中移除购物项
	 * @param bid 书号
	 */
	public void remove(String bid)
	{
		/*
		 * 将购物项移除,更新总价
		 */
		CartItem cartItem=map.remove(bid);
		total=total.subtract(cartItem.getSubtotal());
	}
	/***
	 * 清空购物车
	 */
	public void clear()
	{
		map.clear();
		total=new BigDecimal(0);
	}
}
CartItem.java代码如下:
package cn.my.bookstore.cart;



import java.math.BigDecimal;

import cn.my.bookstore.book.Book;
/***
 * 购物项 由书,数量,小计算出来
 * @author wulaoern
 *
 */
public class CartItem {
	private Book book;//图书类,在数据库中,
	private int count; //数量
	public Book getBook() {
		return book;
	}
	public void setBook(Book book) {
		this.book = book;
	}
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	public BigDecimal getSubtotal() {
		return book.getPrice().multiply(new BigDecimal(count));
	}
	

}

在CartItem中用到了一个Book类,在此把代码贴出来:
package cn.my.bookstore.book;

import java.math.BigDecimal;

import cn.my.bookstore.category.Category;

public class Book {
	/*
	 *   `bid` char(32) NOT NULL,
	  `bname` varchar(100) DEFAULT NULL,
	  `price` decimal(10,2) DEFAULT NULL,
	  `author` varchar(50) DEFAULT NULL,
	  `image` varchar(200) DEFAULT NULL,
	  `cid` char(32) DEFAULT NULL,
	  `isdel` tinyint(1) DEFAULT NULL,
	 */
	private String bid;
	private String bname;
	private BigDecimal price=new BigDecimal(0);
	private String author;
	private String image;
	/*
	 *  因为分类与图书是一对多  数据库中存的是关系  
	 *  所以需要在多的一方  图书方 创建一个字段与 分类一方 的主键对应.
	 *  现在Java语言 是面向对象的.所以说在Book类中存的是Category的对象. ORM
	 *  O:Object R:Relation M:Mapping  --- Hibernate
	 */
	private Category category;
	private int isdel;
	public String getBid() {
		return bid;
	}
	public void setBid(String bid) {
		this.bid = bid;
	}
	public String getBname() {
		return bname;
	}
	public void setBname(String bname) {
		this.bname = bname;
	}
	public BigDecimal getPrice() {
		return price;
	}
	public void setPrice(BigDecimal price) {
		this.price = price;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getImage() {
		return image;
	}
	public void setImage(String image) {
		this.image = image;
	}
	public Category getCategory() {
		return category;
	}
	public void setCategory(Category category) {
		this.category = category;
	}
	public int getIsdel() {
		return isdel;
	}
	public void setIsdel(int isdel) {
		this.isdel = isdel;
	}
	
}

 
购物车的封装类做好了,就该做购物车了,

添加到购物车

在网站前台,将图书bid和购买数量传到servlet中,servlet通过bid获得将该图书对象,之后将图书对象和购买数量封装到CartItem对象中。从session中获得cart,注意,此处应判断session中是否存在cart,之后调用cart类的add()方法进行将物品添加到购物车。

其他

而购车的购物项的删除与清空就根据cart类中提供的方法传递参数进行操作就可以了。

2.订单

订单需要根据数据库中的信息进行提取。根据分析,一个订单中不只一个订单项,同样有两个类order类和orderItem类。OrderItem类用来封装订单中的具体的订单项,也就是图书信息。而Order类用来存放OrderItem.
OrderItem.java如下:
package cn.my.bookstore.order;

import java.math.BigDecimal;

import cn.my.bookstore.book.Book;

/**
 * 订单项类
 * CREATE TABLE `orderitem` (
	  `itemid` char(32) NOT NULL,
	  `count` int(11) DEFAULT NULL,
	  `subtotal` decimal(10,2) DEFAULT NULL,
	  `bid` char(32) DEFAULT NULL,
	  `oid` char(32) DEFAULT NULL,
	  PRIMARY KEY (`itemid`),
	  KEY `bid` (`bid`),
	  KEY `oid` (`oid`),
	  CONSTRAINT `orderitem_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `book` (`bid`),
	  CONSTRAINT `orderitem_ibfk_2` FOREIGN KEY (`oid`) REFERENCES `orders` (`oid`)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 * @author wulaoern
 *
 */
public class OrderItem {
	private String itemId;
	private int count;
	private BigDecimal subTotal=new BigDecimal(0); //小计,即钱
	private Book book;
	private Order order;
	public String getItemId() {
		return itemId;
	}
	public void setItemId(String itemId) {
		this.itemId = itemId;
	}
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	public BigDecimal getSubTotal() {
		return subTotal;
	}
	public void setSubTotal(BigDecimal subTotal) {
		this.subTotal = subTotal;
	}
	public Book getBook() {
		return book;
	}
	public void setBook(Book book) {
		this.book = book;
	}
	public Order getOrder() {
		return order;
	}
	public void setOrder(Order order) {
		this.order = order;
	}

}
Order.java如下
package cn.my.bookstore.order;

import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import cn.my.bookstore.cart.CartItem;
import cn.my.bookstore.user.User;

/**
 * 订单类
 * CREATE TABLE `orders` (
	  `oid` char(32) NOT NULL,
	  `total` decimal(10,2) DEFAULT NULL,
	  `ordertime` timestamp,
	  `state` int(11) DEFAULT NULL,
	  `address` varchar(100) DEFAULT NULL,
	  `uid` char(32) DEFAULT NULL,
	  PRIMARY KEY (`oid`),
	  KEY `uid` (`uid`),
	  CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8;
	
 * @author wulaoern
 *
 */
public class Order {
	private String oid;
	private BigDecimal total=new BigDecimal(0);
	private Date orderTime;
	private String address;
	private User user;
	private int state;
	//因为需要通过订单号差查询订单项,而一个订单包括很多订单项,所以将订单项也进行封装
	private Set<OrderItem> orderItems=new LinkedHashSet<OrderItem>();
	public void addOrdertItem(OrderItem orderItem)
	{
		orderItems.add(orderItem);
	}
	public int getState() {
		return state;
	}
	public void setState(int state) {
		this.state = state;
	}
	public String getOid() {
		return oid;
	}
	public void setOid(String oid) {
		this.oid = oid;
	}
	public BigDecimal getTotal() {
		return total;
	}
	public void setTotal(BigDecimal total) {
		this.total = total;
	}
	public Date getOrderTime() {
		return orderTime;
	}
	public void setOrderTime(Date orderTime) {
		this.orderTime = orderTime;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	public Set<OrderItem> getOrderItems() {
		return orderItems;
	}
	public void setOrderItems(Set<OrderItem> orderItems) {
		this.orderItems = orderItems;
	}
	
	
}
 

下订单

这里做的下订单是一次性将购物车中的所有购物项下订单。
在点击下订单时候,在servlet中对数据进行封装,注意cart和user都是从session中获得的,这里也可以理解为将cartItem转到orderItem中
 
/*******************封装订单**********************/
				Order order=new Order();
				order.setOid(CommonsUUID.getUUID()); //这个方法是获取随机字符串作为id
				order.setTotal(cart.getTotal());
				order.setUser(user);
				order.setState(1);//1代表未付款
				/*******************封装订单项**************/
				//因为一个订单中不止一个订单项,订单项从购物车中得到,之后将每一个订单项封装
				for (CartItem cartItem : cart.getCartItems()) {
					OrderItem orderItem=new OrderItem();
					orderItem.setBook(cartItem.getBook());
					orderItem.setCount(cartItem.getCount());
					orderItem.setItemId(CommonsUUID.getUUID());
					orderItem.setSubTotal(cartItem.getSubtotal());
				    order.addOrdertItem(orderItem);					
				}
经过这样一搞,order对象就满载订单项了,可以向下一层进行操作了。
在dao中,需要对两个表进行插入操作了,orders表和orderitem表。
public void addOrder(Order order) throws SQLException {
		QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
		String sql="insert into orders values (?,?,null,?,?,?)";
		Object[] param={order.getOid(),order.getTotal(),order.getState(),
				order.getAddress(),order.getUser().getUid()};
		qr.update(sql,param);
		for (OrderItem orderItem : order.getOrderItems()) {
			String sql2="insert into orderitem values (?,?,?,?,?)";
			Object[] param2={orderItem.getItemId(),orderItem.getCount(),orderItem.getSubTotal(),
					orderItem.getBook().getBid(),order.getOid()};
			qr.update(sql2, param2);
			
			
		}

这样一来,两个表中就有了订单数据了。
但是在下订单之后需要立马显示该次订单信息。所以还得到数据库中查找该订单信息,这个订单还是热的,比较容易查找,通过订单号oid就可以轻松找到详细信息。
public Order findOrderByOid(String oid) throws SQLException, IllegalAccessException, InvocationTargetException {
		QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
		String sql="select * from orders where oid=?";
		//按照订单号查询了订单信息,并进行封装,还缺少订单项,但是并不完整,还需要继续封装
		Order order=qr.query(sql, new BeanHandler<Order>(Order.class),oid);
		//order中还得继续封装orderItem而每一个订单有至少一个订单项,订单项中也还得封装图书,按照功能需求来讲,
		//下完订单后,得将本次订单的所有订单项详情显示
		String sql2="select * from orderitem o,book b where o.bid=b.bid and oid=?";
		//将所有的数据存到了一个list中,而list中存放的是订单项的map信息
		List<Map<String, Object>> mapList=qr.query(sql2, new MapListHandler(),oid);
		//循环进行封装
		for (Map<String, Object> map : mapList) {
			//先封装书
			Book book=new Book();
			BeanUtils.populate(book, map);
			//封装订单项
			OrderItem orderItem=new OrderItem();
			BeanUtils.populate(orderItem, map);
			orderItem.setBook(book);
			//继续封装order
			order.addOrdertItem(orderItem);
		}
		return order;
	}
这样一来就又获得了order对象,随便对他进行操作吧。

查看我的订单

其实查看我的订单只需要用户id   uid就可以。之后根据数据库中表之间的连接将数据获取出来
public List<Order> findMyOrders(String uid) throws Exception {
		List <Order> orders=new ArrayList<Order>();
		QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
		//先根据用户ID查询出用户的订单信息,每个用户不只一个订单
		String sql="select * from orders where uid=?";
		List<Map<String, Object>> maplist= qr.query(sql, new MapListHandler(),uid);
		for (Map<String, Object> map : maplist) {
			
			//获取oid,根据oid查 询订单项目
			String oid=(String) map.get("oid");
			//调用方法对order的
			Order order=findOrderByOid(oid);
			//将查找的数据进行封装
			BeanUtils.populate(order, map);
			orders.add(order); //这个用的是上一个方法
		}
		return orders;
	}
这样一个个的订单就被装到orders中了,对他随便操作吧。
 

结算

结算的话,可以调用各银行的接口,或者调用一些**宝提供的接口完成付账,再付账后,将数据库中的响应信息更新即可。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值