【SSH网上商城项目实战17】购物车基本功能的实现

上一节我们将商品的详细页面做完了,并使用了Hibernate的二级缓存加载详细页面来提高系统的性能。这节我们开始做购物车部分。

1. 添加新的表

首先我们向数据库中添加几张表:用户表、订单状态表、订单表(购物车表)以及购物项表。用户表中存有用户的基本信息,订单状态表中主要存储订单的状态,比如已发货这种,订单表主要存储用户的信息和订单的状态,所以跟用户表和订单状态表关联,购物项表存储某个商品以及所属的订单,所以跟商品表和订单表相关联。具体的表信息见下面的sql语句:

/*============================*/
/* Table: 用户表结构 		      */
/*============================*/
create table user
(
   /* 用户编号,自动增长 */
   id                  int primary key not null auto_increment,
   /* 用户登录名 */
   login               varchar(20),
   /* 用户真实姓名 */
   name                varchar(20),
   /* 用户登录密码 */
   pass                varchar(20),
   /* 用户性别 */
   sex                 varchar(20),
   /* 用户电话 */
   phone               varchar(20),
   /* 用户Email */
   email               varchar(20)
);

/*=============================*/
/* Table: 订单状态表结构 		       */
/*=============================*/
create table status
(
   /* 状态编号,自动增长 */
   id                  int primary key not null auto_increment,
   /* 订单状态 */
   status               varchar(10)
);

/*=============================*/
/* Table: 购物车(订单)表结构		   */
/*=============================*/
create table forder
(
   /* 订单编号,自动增长 */
   id                  int primary key not null auto_increment,
   /* 收件人名字 */
   name                varchar(20),
   /* 收件人电话 */
   phone               varchar(20),
   /* 配送信息 */
   remark              varchar(20),
   /* 下单日期 */
   date                timestamp default CURRENT_TIMESTAMP,
   /* 订单总金额 */
   total               decimal(8,2),
   /* 收件人邮编 */
   post                varchar(20),
    /* 收件人邮编 */
   address             varchar(200),
   /* 订单状态 */
   sid                 int default 1,
   /* 会员编号 */
   uid                 int,
   constraint sid_FK foreign key(sid) references status(id),
   constraint uid_FK foreign key(uid) references user(id)
);

/*=============================*/
/* Table: 购物项表结构 		       */
/*=============================*/

create table sorder
(
   /* 购物项编号,自动增长 */
   id                  int primary key not null auto_increment,
   /* 被购买商品的名称 */
   name                varchar(20),
   /* 购买时商品的价格 */
   price               decimal(8,2),
   /* 购买的数量 */
   number              int not null,
   /* 所属商品编号 */
   pid                  int,
   /* 此订单项,所属的订单编号 */
   fid                  int,
   constraint pid_FK foreign key(pid) references product(id),
   constraint fid_FK foreign key(fid) references forder(id)
);

然后我们将这些表通过逆向工程转换为POJO,具体不在赘述。

2. 购物车的后台逻辑

2.1 Service层的逻辑

当用户将某个商品加入购物车时,我们首先要通过商品的id获取该商品信息,然后将该商品添加到购物车中,在添加之前,我们首先得判断当前session中有没有购物车,如果没有的话,我们得先创建一个购物车,如果有,我们将当前的购物项添加到购物车里,在添加之前,需要先判断该购物项在购物车中是否已经存在了,如果存在了只需要增加相应的购物数量即可,如果不存在则添加,然后计算购物总价格,最后将购物车存到session中。整个流程见下面的示意图:

接下来我们来实现具体的逻辑,首先新建两个Service接口:SorderService和ForderService。SorderService中主要定义了两个方法:将用户添加的商品转换为购物项,然后将购物项添加到购物车;ForderService中主要定义了计算购物车总价格的方法,如下:

//SorderService接口
public interface SorderService extends BaseService<Sorder> {
	//添加购物项,返回新的购物车
	public Forder addSorder(Forder forder, Product product);
	//把商品数据转化为购物项
	public Sorder productToSorder(Product product);
}

//ForderService接口
public interface ForderService extends BaseService<Forder> {
    //计算购物总价格
    public double cluTotal(Forder forder);
}

然后我们具体实现这两个接口:

//SorderServiceImpl实现类
@Service("sorderService")
public class SorderServiceImpl extends BaseServiceImpl<Sorder> implements
		SorderService {

	@Override
	public Forder addSorder(Forder forder, Product product) {
		boolean isHave = false; //用来标记有没有重复购物项
		//拿到当前的购物项
		Sorder sorder = productToSorder(product);
		//判断当前购物项是否重复,如果重复,则添加数量即可
		for(Sorder old : forder.getSorders()) {
			if(old.getProduct().getId().equals(sorder.getProduct().getId())) {
				//购物项有重复,添加数量即可
				old.setNumber(old.getNumber() + sorder.getNumber());
				isHave = true;
				break;
			}
		}
		//当前购物项在购物车中不存在,新添加即可
		if(!isHave) {
			forder.getSorders().add(sorder);
		}
		return forder;
	}

	@Override
	public Sorder productToSorder(Product product) {
		Sorder sorder = new Sorder();
		sorder.setName(product.getName());
		sorder.setNumber(1);
		sorder.setPrice(product.getPrice());
		sorder.setProduct(product);
		return sorder;
	}
}

//ForderServiceImpl实现类
@Service("forderService")
public class ForderServiceImpl extends BaseServiceImpl<Forder> implements ForderService {

    @Override
    public double cluTotal(Forder forder) {

        double total = 0.0;
        for(Sorder sorder : forder.getSorders()) {
            total += sorder.getNumber() * sorder.getPrice();
        }
        return total;
    }
    
}

然后我们需要将这两个bean注入到BaseAction中,供SorderAction使用:

@Controller("baseAction")
@Scope("prototype")
public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {

	//省略其他无关代码……

    @Resource
	protected ForderService forderService;
	@Resource
	protected SorderService sorderService;

}

好了,Service层的逻辑做完了,接下来准备做Action部分:

2.2 Action部分的逻辑

我们新建一个SorderAction,将上面的逻辑图上显示的流程走一遍即可完成添加购物车的逻辑了。代码如下:

@Controller
@Scope("prototype")
public class SorderAction extends BaseAction<Sorder> {
	public String addSorder() {

		//1. 根据product.id获取相应的商品数据
		Product product = productService.get(model.getProduct().getId());

		//2. 判断当前session是否有购物车,如果没有则创建
		if(session.get("forder") == null) {
			//创建新的购物车,存储到session中
			session.put("forder", new Forder(new HashSet<Sorder>()));
		} 

		//3. 把商品信息转化为sorder,并且添加到购物车中(判断购物项是否重复)
		Forder forder = (Forder) session.get("forder");
		forder = sorderService.addSorder(forder, product);

		//4. 计算购物的总价格
		forder.setTotal(forderService.cluTotal(forder));
		//5. 把新的购物车存储到session中
		session.put("forder", forder);
		return "showCart";
	}
}

配置一下struts.xml文件:

<action name="sorder_*" class="sorderAction" method="{1}">
	<result name="showCart">/showCart.jsp</result>
</action>

然后跳转到购物车显示页面showCart.jsp,showCart.jsp中关于购物车部分的前台程序如下:

3. 前台链接的跳转

后台部分全部做完了,接下来将前台detail.jsp页面添加购物车的链接地址该成访问SorderAction即可:

这样就能正确跳转了,下面我们看一下购物车显示页面的具体效果:

这样我们购物车的基本功能就做完了,后面我们再对其做一些完善。

(注:到最后我会提供整个项目的源码下载!欢迎大家收藏或关注)

相关阅读:http://blog.csdn.net/column/details/str2hiberspring.html

_____________________________________________________________________________________________________________________________________________________

-----乐于分享,共同进步!

-----更多文章请看:http://blog.csdn.net/eson_15

时间: 2024-09-30 10:25:31

【SSH网上商城项目实战17】购物车基本功能的实现的相关文章

【SSH网上商城项目实战27】域名空间的申请和项目的部署及发布

前面陆陆续续的完成了网上商城的一些基本功能,虽然还有很多地方有待完善,但是不影响项目的部署和发布,我们可以先来玩一把,这一节主要介绍下域名空间的申请以及项目的部署和发布流程. 1. 域名空间的申请 作为一个伟大的屌丝,肯定没钱买域名空间,很自然的想到去申请个免费的,现在免费的域名空间也很多,我在福佳jsp技术网上申请了一个试用期是15天的,大家也可以去申请个玩玩,反正作为学习,这已经足够了,当然,如果要长期的肯定要付费的.注册过程我截几个图,如下: 然后下一步,最后开通如下: 建议把上面这些信息

【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示

网上商城首页都有热门商品,那么这些商品的点击率是很高的,当用户点击某个热门商品后需要进入商品的详细信息页面,就像淘宝里面那样.那么每次点击都要去后台查询一下该商品的详细信息,就会发送相应的sql语句,每次刷新一下详细页面也会发sql语句,这样的话,性能肯定会受到很大的影响.那么使用Hibernate的二级缓存就可以解决这个问题. 有些人可能会想,我们可以使用重定向,这样的话,在用户第一次访问的时候把信息查出来放到session中,以后每次用户刷新就可以去session中拿了,这样就不用去数据库中

【SSH网上商城项目实战21】从Demo中看易宝支付的流程

这一节我们先写一个简单点的Demo来测试易宝支付的流程,熟悉这个流程后,再做实际的开发,因为是一个Demo,所以我没有考虑一些设计模式的东西,就是直接实现支付功能.实现支付功能需要易宝给我们提供的API.那么问题来了,使用第三方支付平台最主要的一件事就是获取该平台的API,我们首先得获取他们的API以及开发文档,然后才可以做进一步的开发. 1. 获取易宝的API 获取API的第一步,要在易宝上注册一个账号,这个账号是商家的账号,后面买家付款后,会将钱款存入该账号中,然后商家自己提取到银行卡,易宝

【SSH网上商城项目实战20】在线支付平台的介绍

之前已经完成了首页的显示,用户添加购物车,确认订单等功能,下面就是支付功能的开发了.用户确认了订单后会直接跳转到支付页面进行在线支付,在线支付需要第三方的接口,这一节主要介绍一些关于第三方支付的内容,从下一节开始,我们真正开发在线支付模块. 1. 在线支付介绍 在线支付是指卖方与买方通过因特网上的电子商务网站进行交易时,银行为其提供网上资金结算服务的一种业务.它为企业和个人提供了一个安全.快捷.方便的电子商务应用环境和网上资金结算工具.在线支付不仅帮助企业实现了销售款项的快速归集,缩短收款周期,

【SSH网上商城项目实战25】使用java email给用户发送邮件

当用户购买完商品后,我们应该向用户发送一封邮件,告诉他订单已生成之类的信息,邮箱地址是从用户的基本信息中获取,好了,首先我们来看一下Java中发送邮件的方法. 1. java中发送email的方法     在完善这个项目之前,先来回顾一下java中是如何发送邮件的,首先肯定需要发送邮件的jar包:mail.jar,导入到lib目录下,好了,下面我们先写一个普通的java程序来回顾一下java email的知识点: public class SendEmailDemo { public stati

【SSH网上商城项目实战19】订单信息的级联入库以及页面的缓存问题

购物车这一块还剩最后两个问题,就是订单信息的级联入库和页面缓存,这里的信息是指购物车和购物项,即我们将购物车的信息存入数据库的同时,也存入每个购物项的信息,而且外键都关联好,这涉及到了Hibernate中的级联入库问题:页面缓存问题指的是当用户确认了订单后,如果点后退,又会回到订单确认页面,刚刚的订单确认页面又出来了,而且session还在,信息还是刚刚的信息,这明显不是我们想要的结果,我们会在后面一一分析.这一节主要来讨论订单信息的级联入库以及页面的缓存问题. 1. 订单信息的级联入库 Hib

【SSH网上商城项目实战18】过滤器实现购物登录功能的判断

上一节我们做完了购物车的基本操作,但是有个问题是:当用户点击结算时,我们应该做一个登录的判断,判断用户有没有登录,没有登录的话,得首先让用户登录.这就用到了过滤器的技术了,过滤器是专门拦截页面请求的,它与拦截器的原理差不多,拦截器是专门拦截Action请求的,所以各有所用,如果直接是页面的跳转,不经过Action的话,我们只要写一个拦截器即可,如果需要跳转到一个Action处理,那么我们就得写一个拦截器. 1. 登录跳转的原理 先说一下实现原理:写一个过滤器,在web.xml中配置一下需要拦截的

【SSH网上商城项目实战14】商城首页UI的设计

前面我们利用EasyUI和SSH搭建好了后台的基本框架,做好了后台的基本功能,包括对商品类别的管理和商品的管理等,这一节我们开始搭建前台页面. 做首页的思路:假设现在商品的业务逻辑都有了,首先我们需要创建一个监听器,在项目启动时将首页的数据查询出来放到application里,即在监听器里调用后台商品业务逻辑的方法. 1.  首页商品显示逻辑 在首页,我们只显示商品热点类别中的前几个商品,比如热点类别有儿童休闲类,女性休闲类,男性休闲类,那我们会有三个板块来显示不同的商品类,每个类别里再显示几个

【SSH网上商城项目实战10】商品类基本模块的搭建

前面我们完成了与商品类别相关的业务逻辑,接下来我们开始做具体商品部分. 1. 数据库建表并映射Model 首先我们在数据库中新建一张表,然后使用逆向工程将表映射成Model类,表如下: /*=============================*/ /* Table: 商品表结构 */ /*=============================*/ create table product ( /* 商品编号,自动增长 */ id int primary key not null aut