【SSH網上商城項目實戰17】購物車基本功能的實現

        上一節我們將商品的詳細頁面做完了,並使用了hibernate的二級緩存加載詳細頁面來提高系統的性能。這節我們開始做購物車部分。

1. 添加新的表

        首先我們向數據庫中添加幾張表:用戶表、訂單狀態表、訂單表(購物車表)以及購物項表。用戶表中存有用戶的基本信息,訂單狀態表中主要存儲訂單的狀態,比如已發貨這種,訂單表主要存儲用戶的信息和訂單的狀態,所以跟用戶表和訂單狀態表關聯,購物項表存儲某個商品以及所屬的訂單,所以跟商品表和訂單表相關聯。具體的表信息見下面的sql語句:

  1. /*============================*/  
  2. /* Table: 用戶表結構               */  
  3. /*============================*/  
  4. create table user  
  5. (  
  6.    /* 用戶編號,自動增長 */  
  7.    id                  int primary key not null auto_increment,  
  8.    /* 用戶登錄名 */  
  9.    login               varchar(20),  
  10.    /* 用戶真實姓名 */  
  11.    name                varchar(20),  
  12.    /* 用戶登錄密碼 */  
  13.    pass                varchar(20),  
  14.    /* 用戶性別 */  
  15.    sex                 varchar(20),  
  16.    /* 用戶電話 */  
  17.    phone               varchar(20),  
  18.    /* 用戶Email */  
  19.    email               varchar(20)  
  20. );  
  21.   
  22. /*=============================*/  
  23. /* Table: 訂單狀態表結構              */  
  24. /*=============================*/  
  25. create table status  
  26. (  
  27.    /* 狀態編號,自動增長 */  
  28.    id                  int primary key not null auto_increment,  
  29.    /* 訂單狀態 */  
  30.    status               varchar(10)  
  31. );  
  32.   
  33. /*=============================*/  
  34. /* Table: 購物車(訂單)表結構           */  
  35. /*=============================*/  
  36. create table forder  
  37. (  
  38.    /* 訂單編號,自動增長 */  
  39.    id                  int primary key not null auto_increment,  
  40.    /* 收件人名字 */  
  41.    name                varchar(20),  
  42.    /* 收件人電話 */  
  43.    phone               varchar(20),  
  44.    /* 配送信息 */  
  45.    remark              varchar(20),  
  46.    /* 下單日期 */  
  47.    date                timestamp default CURRENT_TIMESTAMP,  
  48.    /* 訂單總金額 */  
  49.    total               decimal(8,2),  
  50.    /* 收件人郵編 */  
  51.    post                varchar(20),  
  52.     /* 收件人郵編 */  
  53.    address             varchar(200),  
  54.    /* 訂單狀態 */  
  55.    sid                 int default 1,  
  56.    /* 會員編號 */  
  57.    uid                 int,  
  58.    constraint sid_FK foreign key(sid) references status(id),  
  59.    constraint uid_FK foreign key(uid) references user(id)  
  60. );  
  61.   
  62. /*=============================*/  
  63. /* Table: 購物項表結構               */  
  64. /*=============================*/  
  65.   
  66. create table sorder  
  67. (  
  68.    /* 購物項編號,自動增長 */  
  69.    id                  int primary key not null auto_increment,  
  70.    /* 被購買商品的名稱 */  
  71.    name                varchar(20),  
  72.    /* 購買時商品的價格 */  
  73.    price               decimal(8,2),  
  74.    /* 購買的數量 */  
  75.    number              int not null,  
  76.    /* 所屬商品編號 */  
  77.    pid                  int,  
  78.    /* 此訂單項,所屬的訂單編號 */  
  79.    fid                  int,  
  80.    constraint pid_FK foreign key(pid) references product(id),  
  81.    constraint fid_FK foreign key(fid) references forder(id)  
  82. );  
/*============================*/
/* 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中主要定義了計算購物車總價格的方法,如下:

  1. //SorderService接口  
  2. public interface SorderService extends BaseService<Sorder> {  
  3.     //添加購物項,返回新的購物車  
  4.     public Forder addSorder(Forder forder, Product product);  
  5.     //把商品數據轉化爲購物項  
  6.     public Sorder productToSorder(Product product);  
  7. }  
  8.   
  9. //ForderService接口  
  10. public interface ForderService extends BaseService<Forder> {  
  11.     //計算購物總價格  
  12.     public double cluTotal(Forder forder);  
  13. }  
//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);
}
        然後我們具體實現這兩個接口:

  1. //SorderServiceImpl實現類  
  2. @Service(“sorderService”)  
  3. public class SorderServiceImpl extends BaseServiceImpl<Sorder> implements  
  4.         SorderService {  
  5.   
  6.     @Override  
  7.     public Forder addSorder(Forder forder, Product product) {  
  8.         boolean isHave = false//用來標記有沒有重複購物項  
  9.         //拿到當前的購物項  
  10.         Sorder sorder = productToSorder(product);  
  11.         //判斷當前購物項是否重複,如果重複,則添加數量即可  
  12.         for(Sorder old : forder.getSorders()) {  
  13.             if(old.getProduct().getId().equals(sorder.getProduct().getId())) {  
  14.                 //購物項有重複,添加數量即可  
  15.                 old.setNumber(old.getNumber() + sorder.getNumber());  
  16.                 isHave = true;  
  17.                 break;  
  18.             }  
  19.         }  
  20.         //當前購物項在購物車中不存在,新添加即可  
  21.         if(!isHave) {  
  22.             forder.getSorders().add(sorder);  
  23.         }  
  24.         return forder;  
  25.     }  
  26.   
  27.     @Override  
  28.     public Sorder productToSorder(Product product) {  
  29.         Sorder sorder = new Sorder();  
  30.         sorder.setName(product.getName());  
  31.         sorder.setNumber(1);  
  32.         sorder.setPrice(product.getPrice());  
  33.         sorder.setProduct(product);  
  34.         return sorder;  
  35.     }  
  36. }  
  37.   
  38. //ForderServiceImpl實現類  
  39. @Service(“forderService”)  
  40. public class ForderServiceImpl extends BaseServiceImpl<Forder> implements ForderService {  
  41.   
  42.     @Override  
  43.     public double cluTotal(Forder forder) {  
  44.   
  45.         double total = 0.0;  
  46.         for(Sorder sorder : forder.getSorders()) {  
  47.             total += sorder.getNumber() * sorder.getPrice();  
  48.         }  
  49.         return total;  
  50.     }  
  51.       
  52. }  
//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使用:

  1. @Controller(“baseAction”)  
  2. @Scope(“prototype”)  
  3. public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {  
  4.   
  5.     //省略其他無關代碼……  
  6.   
  7.     @Resource  
  8.     protected ForderService forderService;  
  9.     @Resource  
  10.     protected SorderService sorderService;  
  11.   
  12. }  
@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,將上面的邏輯圖上顯示的流程走一遍即可完成添加購物車的邏輯了。代碼如下:

  1. @Controller  
  2. @Scope(“prototype”)  
  3. public class SorderAction extends BaseAction<Sorder> {  
  4.     public String addSorder() {  
  5.           
  6.         //1. 根據product.id獲取相應的商品數據  
  7.         Product product = productService.get(model.getProduct().getId());  
  8.           
  9.         //2. 判斷當前session是否有購物車,如果沒有則創建  
  10.         if(session.get(“forder”) == null) {  
  11.             //創建新的購物車,存儲到session中  
  12.             session.put(”forder”new Forder(new HashSet<Sorder>()));  
  13.         }   
  14.   
  15.         //3. 把商品信息轉化爲sorder,並且添加到購物車中(判斷購物項是否重複)  
  16.         Forder forder = (Forder) session.get(”forder”);  
  17.         forder = sorderService.addSorder(forder, product);  
  18.           
  19.         //4. 計算購物的總價格  
  20.         forder.setTotal(forderService.cluTotal(forder));  
  21.         //5. 把新的購物車存儲到session中  
  22.         session.put(”forder”, forder);  
  23.         return “showCart”;  
  24.     }  
  25. }  
@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文件:

  1. <action name=“sorder_*” class=“sorderAction” method=“{1}”>  
  2.     <result name=“showCart”>/showCart.jsp</result>  
  3. </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

_____________________________________________________________________________________________________________________________________________________

—–樂於分享,共同進步!

—–更多文章請看:http://blog.csdn.net/eson_15

document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
    <div id="digg" articleid="51418350">
        <dl id="btnDigg" class="digg digg_enable" onclick="btndigga();">

             <dt>頂</dt>
            <dd>11</dd>
        </dl>


        <dl id="btnBury" class="digg digg_enable" onclick="btnburya();">

              <dt>踩</dt>
            <dd>0</dd>               
        </dl>

    </div>
 <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank">&nbsp;</a>   </div>
<div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank">&nbsp;</a></div>
<script type="text/javascript">
            function btndigga() {
                $(".tracking-ad[data-mod='popu_222'] a").click();
            }
            function btnburya() {
                $(".tracking-ad[data-mod='popu_223'] a").click();
            }
        </script>

<div style="clear:both; height:10px;"></div>


    <div class="similar_article" style="">
            <h4>我的同類文章</h4>
            <div class="similar_c" style="margin:20px 0px 0px 0px">
                <div class="similar_c_t">
                            <label class="similar_cur">
                                <span style="cursor:pointer" onclick="GetCategoryArticles('6228419','eson_15','foot','51418350');">●  項目實戰<em>(29)</em></span>
                            </label>
                            <label class="">
                                <span style="cursor:pointer" onclick="GetCategoryArticles('6214186','eson_15','foot','51418350');">------【SSH網上商城】<em>(29)</em></span>
                            </label>
                </div>

                <div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
                    <a href="http://blog.csdn.net" style="display:none" target="_blank">http://blog.csdn.net</a>
                    <ul class="similar_list fl"><li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51506334" id="foot_aritcle_51506334undefined07923260436447199" target="_blank" title="【SSH網上商城項目實戰29】使用JsChart技術在後臺顯示商品銷售報表">【SSH網上商城項目實戰29】使用JsChart技術在後臺顯示商品銷售報表</a><span>2016-05-26</span><label><i>閱讀</i><b>6059</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51484247" id="foot_aritcle_51484247undefined4768835685464923" target="_blank" title="【SSH網上商城項目實戰27】域名空間的申請和項目的部署及發佈">【SSH網上商城項目實戰27】域名空間的申請和項目的部署及發佈</a><span>2016-05-23</span><label><i>閱讀</i><b>13823</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51475431" id="foot_aritcle_51475431undefined24466559284061407" target="_blank" title="【SSH網上商城項目實戰26】完成訂單支付後的短信發送功能">【SSH網上商城項目實戰26】完成訂單支付後的短信發送功能</a><span>2016-05-22</span><label><i>閱讀</i><b>4704</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51465067" id="foot_aritcle_51465067undefined005530096470807377" target="_blank" title="【SSH網上商城項目實戰24】Struts2中如何處理多個Model請求">【SSH網上商城項目實戰24】Struts2中如何處理多個Model請求</a><span>2016-05-21</span><label><i>閱讀</i><b>4245</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51452243" id="foot_aritcle_51452243undefined0062675089359605085" target="_blank" title="【SSH網上商城項目實戰22】獲取銀行圖標以及支付頁面的顯示">【SSH網上商城項目實戰22】獲取銀行圖標以及支付頁面的顯示</a><span>2016-05-19</span><label><i>閱讀</i><b>3742</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51441431" id="foot_aritcle_51441431undefined820387173455515" target="_blank" title="【SSH網上商城項目實戰20】在線支付平臺的介紹">【SSH網上商城項目實戰20】在線支付平臺的介紹</a><span>2016-05-18</span><label><i>閱讀</i><b>4107</b></label></li> </ul>

                    <ul class="similar_list fr"><li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51487323" id="foot_aritcle_51487323undefined8876969164530883" target="_blank" title="【SSH網上商城項目實戰28】使用Ajax技術局部更新商品數量和總價">【SSH網上商城項目實戰28】使用Ajax技術局部更新商品數量和總價</a><span>2016-05-24</span><label><i>閱讀</i><b>5337</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51479994" id="foot_aritcle_51479994undefined5001572471017519" target="_blank" title="【SSH網上商城項目實戰30】項目總結(附源碼下載地址)">【SSH網上商城項目實戰30】項目總結(附源碼下載地址)</a><span>2016-05-27</span><label><i>閱讀</i><b>21890</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51475046" id="foot_aritcle_51475046undefined9184912825972149" target="_blank" title="【SSH網上商城項目實戰25】使用java email給用戶發送郵件">【SSH網上商城項目實戰25】使用java email給用戶發送郵件</a><span>2016-05-22</span><label><i>閱讀</i><b>4007</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51464415" id="foot_aritcle_51464415undefined3111782963392702" target="_blank" title="【SSH網上商城項目實戰23】完成在線支付功能">【SSH網上商城項目實戰23】完成在線支付功能</a><span>2016-05-20</span><label><i>閱讀</i><b>8822</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51447492" id="foot_aritcle_51447492undefined24922161472174964" target="_blank" title="【SSH網上商城項目實戰21】從Demo中看易寶支付的流程">【SSH網上商城項目實戰21】從Demo中看易寶支付的流程</a><span>2016-05-18</span><label><i>閱讀</i><b>9653</b></label></li> </ul>
                <a href="http://blog.csdn.net/eson_15/article/category/6228419" class="MoreArticle">更多文章</a></div>
            </div>
        </div>    
<script type="text/javascript">
    $(function () {
        GetCategoryArticles('6228419', 'eson_15','foot','51418350');
    });
</script>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章