您的位置:首页 > 其它

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

2017-03-27 21:12 796 查看

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

1. 添加新的表

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

[sql]
view plain
copy

print?





/*============================*/  
/* 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)  
);  



/*============================*/
/* 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中主要定义了计算购物车总价格的方法,如下:

[java]
view plain
copy

print?





//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);  
}  



//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);
}
        然后我们具体实现这两个接口:

[java]
view plain
copy

print?





//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;  
    }  
      
}  



//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使用:

[java]
view plain
copy

print?





@Controller("baseAction")  
@Scope("prototype")  
public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {  
  
    //省略其他无关代码……  
  
    @Resource  
    protected ForderService forderService;  
    @Resource  
    protected SorderService sorderService;  
  
}  



@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,将上面的逻辑图上显示的流程走一遍即可完成添加购物车的逻辑了。代码如下:

[java]
view plain
copy

print?





@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";  
    }  
}  



@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文件:

[html]
view plain
copy

print?





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



<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/article/details/51479994
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: