1)用戶沒登陸用戶名和密碼,添加商品, 關閉瀏覽器再打開后 不登錄用戶名和密碼 問:購物車商品還在嗎?
2)用戶登陸了用戶名密碼,添加商品,關閉瀏覽器再打開后 不登錄用戶名和密碼 問:購物車商品還在嗎?
3)用戶登陸了用戶名密碼,添加商品, 關閉瀏覽器,然后再打開,登陸用戶名和密碼 問:購物車商品還在嗎?
4)用戶登陸了用戶名密碼,添加商品, 關閉瀏覽器 外地老家打開瀏覽器 登陸用戶名和密碼 問:購物車商品還在嗎?
上面四個問題都是以京東為模板, 那么大家猜猜結果是什么呢?
1)在
2)不在了
3)在
4)在
如果你能夠猜到答案, 那么說明你真的很棒, 那么關於這四點是怎么實現的呢? (如果有不認可的小伙伴可以用京東實驗一下)
下面我們就來講解下購物車的原理,最后再來說下具體的code實現.
1)用戶沒有登錄, 添加商品, 此時的商品是被添加到了瀏覽器的Cookie中, 所以當再次訪問時(不登錄),商品仍然在Cookie中, 所以購物車中的商品還是存在的.
2)用戶登錄了,添加商品, 此時會將Cookie中和用戶選擇的商品都添加到購物車中, 然后刪除Cookie中的商品. 所以當用戶再次訪問(不登錄),此時Cookie中的購物車商品已經被刪除了, 所以此時購物車中的商品不在了.
3)用戶登錄, 添加商品,此時商品被添加到數據庫做了持久化存儲, 再次打開登錄用戶名和密碼, 該用戶選擇的商品肯定還是存在的, 所以購物車中的商品還是存在的.
4)理由3)
這里再說下 沒登錄 保存商品到Cookie的優點以及保存到Session和數據庫的對比:
1:Cookie: 優點: 保存用戶瀏覽器(不用浪費我們公司的服務器) 缺點:Cookie禁用,不提供保存
2:Session:(Redis : 浪費大量服務器內存:實現、禁用Cookie) 速度很快
3:數據庫(Mysql、Redis、SOlr) 能持久化的就數據庫 速度太慢
那么我今天要講的就是:
-
用戶沒登陸:購物車添加到Cookie中
-
用戶登陸: 保存購物車到Redis中 (不用數據庫)
整體的思路圖解:
接下來就是代碼實例來實現 購物車的功能了:
首先我們看下購物車和購物項兩個JavaBean的設計:
購物車: buyerCart.java
1 public class BuyerCart implements Serializable{ 2 3 /** 4 * 購物車 5 */ 6 private static final long serialVersionUID = 1L; 7 8 //商品結果集 9 private List<BuyerItem> items = new ArrayList<BuyerItem>(); 10 11 //添加購物項到購物車 12 public void addItem(BuyerItem item){ 13 //判斷是否包含同款 14 if (items.contains(item)) { 15 //追加數量 16 for (BuyerItem buyerItem : items) { 17 if (buyerItem.equals(item)) { 18 buyerItem.setAmount(item.getAmount() + buyerItem.getAmount()); 19 } 20 } 21 }else { 22 items.add(item); 23 } 24 25 } 26 27 public List<BuyerItem> getItems() { 28 return items; 29 } 30 31 public void setItems(List<BuyerItem> items) { 32 this.items = items; 33 } 34 35 36 //小計 37 //商品數量 38 @JsonIgnore 39 public Integer getProductAmount(){ 40 Integer result = 0; 41 //計算 42 for (BuyerItem buyerItem : items) { 43 result += buyerItem.getAmount(); 44 } 45 return result; 46 } 47 48 //商品金額 49 @JsonIgnore 50 public Float getProductPrice(){ 51 Float result = 0f; 52 //計算 53 for (BuyerItem buyerItem : items) { 54 result += buyerItem.getAmount()*buyerItem.getSku().getPrice(); 55 } 56 return result; 57 } 58 59 //運費 60 @JsonIgnore 61 public Float getFee(){ 62 Float result = 0f; 63 //計算 64 if (getProductPrice() < 79) { 65 result = 5f; 66 } 67 68 return result; 69 } 70 71 //總價 72 @JsonIgnore 73 public Float getTotalPrice(){ 74 return getProductPrice() + getFee(); 75 } 76 77 }
這里使用了@JsonIgonre注解是因為下面需要將BuyerCart 轉換成Json格式, 而這幾個字段只有get 方法, 所以不能轉換, 需要使用忽略Json.
下面是購物項: buyerItem.java
1 public class BuyerItem implements Serializable{ 2 3 private static final long serialVersionUID = 1L; 4 5 //SKu對象 6 private Sku sku; 7 8 //是否有貨 9 private Boolean isHave = true; 10 11 //購買的數量 12 private Integer amount = 1; 13 14 public Sku getSku() { 15 return sku; 16 } 17 18 public void setSku(Sku sku) { 19 this.sku = sku; 20 } 21 22 public Boolean getIsHave() { 23 return isHave; 24 } 25 26 public void setIsHave(Boolean isHave) { 27 this.isHave = isHave; 28 } 29 30 public Integer getAmount() { 31 return amount; 32 } 33 34 public void setAmount(Integer amount) { 35 this.amount = amount; 36 } 37 38 @Override 39 public int hashCode() { 40 final int prime = 31; 41 int result = 1; 42 result = prime * result + ((sku == null) ? 0 : sku.hashCode()); 43 return result; 44 } 45 46 @Override 47 public boolean equals(Object obj) { 48 if (this == obj) //比較地址 49 return true; 50 if (obj == null) 51 return false; 52 if (getClass() != obj.getClass()) 53 return false; 54 BuyerItem other = (BuyerItem) obj; 55 if (sku == null) { 56 if (other.sku != null) 57 return false; 58 } else if (!sku.getId().equals(other.sku.getId())) 59 return false; 60 return true; 61 }