购物车与下订单项目总结

来源:互联网 发布:linux打开文件乱码 编辑:程序博客网 时间:2024/04/27 21:36

最近跟着视频做了一个购书网站的小项目,有必要总结一下。代码中用到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);//继续封装orderorder.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中了,对他随便操作吧。

结算

结算的话,可以调用各银行的接口,或者调用一些**宝提供的接口完成付账,再付账后,将数据库中的响应信息更新即可。
0 0
原创粉丝点击