框架 day76 濤濤商城專案-使用json模板實現帶分類的產品規格資訊儲存及展示
淘淘商城第四天
講師:入雲龍
1 商品描述的儲存
後臺要接收前臺頁面提交的商品資訊,及商品描述。商品資訊儲存還要儲存商品描述。
資料庫中商品資訊和商品描述是分開儲存的。
1.1 Dao層
把商品描述資訊儲存到tb_item_desc表中。
可以使用逆向工程生成的程式碼
1.2 Service層
接收商品描述呼叫dao把商品描述插入到表中。
引數:String 商品描述
返回值:TaotaoResult
@Override public TaotaoResult createItem(TbItem item, String desc //item補全 //生成商品ID Long itemId = IDUtils.genItemId(); item.setId(itemId); // '商品狀態,1-正常,2-下架,3-刪除', item.setStatus((byte) 1); item.setCreated(new Date()); item.setUpdated(new Date()); //插入到資料庫 itemMapper //新增商品描述資訊 TaotaoResult result = insertItemDesc(itemId, desc); if (result.getStatus() != 200) { throw new Exception(); } return TaotaoResult.ok(); } /** * 新增商品描述 * <p>Title: insertItemDesc</p> * <p>Description: </p> * @param desc */ private TaotaoResult insertItemDesc(Long itemId, String desc) { TbItemDesc itemDesc = new TbItemDesc(); itemDesc.setItemId(itemId); itemDesc.setItemDesc(desc); itemDesc.setCreated(new Date()); itemDesc.setUpdated(new Date()); itemDescMapper.insert(itemDesc); return TaotaoResult.ok(); } |
1.3 Controller
接收商品描述資訊。
2 商品規格
2.1 什麼是商品規格
規格引數:
規格組
|-規格項:規格值
規律:
1、同一類商品的規格項分組相同。
2、同一類商品的規格專案是相同的。規格專案是跟商品關聯。
3、不同商品規格引數的值是不同的
2.2 實現方案
2.2.1 方案一:使用多個表來儲存
1、每一類商品有多個分組
2、每個分組下有多個項
3、每個商品對應不同的規格引數
使用二維表來維護規格資料。
表一:規格組資訊
列名 |
型別 |
長度 |
可以null |
鍵 |
說明 |
Id |
Int |
否 |
P |
主鍵(自增長) |
|
group_name |
varchar |
20 |
否 |
規格分組名稱 |
|
item_cat_id |
Int |
否 |
F |
商品分類id(外來鍵) |
表二:規格項資訊
列名 |
型別 |
長度 |
可以null |
鍵 |
說明 |
Id |
Int |
否 |
P |
主鍵(自增長) |
|
param_name |
varchar |
20 |
否 |
規格專案名稱 |
|
group_id |
Int |
否 |
F |
規格分組id(外來鍵) |
表三:商品規格資訊
列名 |
型別 |
長度 |
可以null |
鍵 |
說明 |
item_id |
Int |
否 |
P |
商品id(聯合主鍵) |
|
param_id |
varchar |
否 |
P |
規格項id(聯合主鍵) |
|
param_value |
varchar |
500 |
否 |
規格資訊 |
2.2.2 Sql語句
SELECT pg.group_name,pk.param_name,pv.param_value FROM tb_item_param_value pv LEFT JOIN tb_item_param_key pk ON pv.param_id = pk.id LEFT JOIN tb_item_param_group pg ON pk.group_id = pg.id WHERE item_id = 855739 |
2.2.3 方案一存在的問題:
1、需要建立多張表來描述規格引數之間的關係。
2、查詢時需要複雜的sql語句查詢。
3、規格引數資料量是商品資訊的幾十倍,資料量十分龐大。查詢時效率很低。
4、如果要求新新增的商品規格項發生改變,之前的商品不變是不能實現的。
2.3 方案二
2.3.1 方案分析
可以使用模板的思路來解決此問題。
1、每一個商品分類對一個規格引數模板。
[
{
"group": "主體", //組名稱
"params": [ // 記錄規格成員
"品牌",
"型號",
"顏色",
"上市年份",
"上市月份"
]
},
{
"group": "網路", //組名稱
"params": [ // 記錄規格成員
"4G",
"3G,
"2G"
]
}
]
2、使用模板
每個商品對應一唯一的規格引數。在新增商品時,可以根據規格引數的模板。生成一個表單。儲存規格引數時。還可以生成規格引數的json資料。儲存到資料庫中。
[
{
"group": "主體",
"params": [
{
"k": "品牌",
"v": "蘋果(Apple)"
},
{
"k": "型號",
"v": "iPhone 6A1589"
},
{
"k": "智慧機",
"v": "是 "
}
]
}
]
2.3.2 實現流程
2.3.3 資料庫儲存
規格引數模板表:
商品的規格引數表:
優點:
1、不需要做多表管理。
2、如果要求新新增的商品規格項發生改變,之前的商品不變是很簡單的。
缺點:
複雜的表單和json之間的轉換。對js的編寫要求很高。
3 建立規格引數模板
3.1 選擇商品分類
選擇商品分類後根據選擇的商品分類到tb_item_param規格引數模板表中取規格模板,取到了說明此商品分類的規格模板已經新增提示不能新增。
如果沒有取得正常新增。
3.1.1 功能分析
請求的url:
/item/param/query/itemcatid/{itemCatId}
引數:itemCatId,從url中獲得
返回值:TaotaoResult
3.1.2 Dao層
從tb_item_param表中根據商品分類id查詢內容。
單表操作。可以實現逆向工程的程式碼。
3.1.3 Service層
功能:接收商品分類id。呼叫mapper查詢tb_item_param表,返回結果TaotaoResult。
@Service public class ItemParamServiceImpl implements ItemParamService { @Autowired private TbItemParamMapper itemParamMapper; @Override public TaotaoResult getItemParamByCid(long cid) { TbItemParamExample example = new TbItemParamExample(); Criteria criteria = example.createCriteria(); criteria.andItemCatIdEqualTo(cid); List<TbItemParam> list = itemParamMapper.selectByExample(example); //判斷是否查詢到結果 if (list != null && list.size() > 0) { return TaotaoResult.ok(list.get(0)); } return TaotaoResult.ok(); } } |
3.1.4 Controller
接收cid引數。呼叫Service查詢規格引數模板。返回TaotaoResult。返回json資料。
@Controller @RequestMapping("/item/param") public class ItemParamController { @Autowired private ItemParamService itemParamService; @RequestMapping("/query/itemcatid/{itemCatId}") @ResponseBody public TaotaoResult getItemParamByCid(@PathVariable Long itemCatId) { TaotaoResult result = itemParamService.getItemParamByCid(itemCatId); returnresult; } } |
3.1.5 Jsp
3.2 提交規格引數模板
3.2.1 需求分析
首先把頁面中所有文字框中的內容轉換成json資料。把json字串提交給後臺。儲存到規格引數表中。
請求的url:
/item/param/save/{cid}
引數:
String paramData
返回值:
TaotaoResult
3.2.2 Dao層
儲存規格引數模板,向tb_item_param表新增一條記錄。可以使用逆向工程生成的程式碼。
3.2.3 Service層
功能:接收TbItemParam物件。 把物件呼叫mapper插入到tb_item_param表中。返回TaotaoResult。
@Override public TaotaoResult insertItemParam(TbItemParam itemParam) { //補全pojo itemParam.setCreated(new Date()); itemParam.setUpdated(new Date()); //插入到規格引數模板表 itemParamMapper.insert(itemParam); return TaotaoResult.ok(); } |
3.2.4 Controller層
功能:接收cid、規格引數模板。建立一TbItemParam物件。呼叫Service返回TaotaoResult。返回json資料。
@RequestMapping("/save/{cid}") @ResponseBody public TaotaoResult insertItemParam(@PathVariable Long cid, String paramData) { //建立pojo物件 TbItemParam itemParam = new TbItemParam(); itemParam.setItemCatId(cid); itemParam.setParamData(paramData); TaotaoResult result = itemParamService.insertItemParam(itemParam); returnresult; } |
4 根據規格引數模板生成表單
在商品新增功能中,讀取此商品對應的規格模板,生成表單。供使用者新增規格引數。
4.1 需求分析
Service修改:
5 儲存商品的規格引數
5.1 需求分析
提交表單之前,先把規格引數表單中的內容轉換成json資料然後跟商品基本資訊、商品描述同時提交給後臺。儲存至資料庫。
轉換後把規格引數的資訊放到表單的hidden域中:
隨著表單的提交同時提交。
5.2 Dao層
需要向tb_item_param_item表中新增資料。
5.3 Service層
接收規格引數的內容,和商品id。拼裝成pojo呼叫mapper 的方法tb_item_param_item表中新增資料返回TaotaoResult。
/** * 新增規格引數 * <p>Title: insertItemParamItem</p> * <p>Description: </p> * @param itemId * @param itemParam * @return */ private TaotaoResult insertItemParamItem(Long itemId, String itemParam) { //建立一個pojo TbItemParamItem itemParamItem = new TbItemParamItem(); itemParamItem.setItemId(itemId); itemParamItem.setParamData(itemParam); itemParamItem.setCreated(new Date()); itemParamItem.setUpdated(new Date()); //向表中插入資料 itemParamItemMapper.insert(itemParamItem); return TaotaoResult.ok(); } |
5.4 表現層
接收規格引數資訊,呼叫Service層儲存商品資訊及商品描述及商品規格引數。返回taotaoResult.
6 展示規格引數
當現實商品詳情頁面時,需要把商品的規格引數根據商品id取出來,生成html展示到頁面。
6.1 Dao層
根據商品id查詢規格引數,單表查詢。
6.2 Service
接收商品id查詢規格引數表。根據返回的規格引數生成html返回html。
@Service public class ItemParamItemServiceImpl implements ItemParamItemService { @Autowired private TbItemParamItemMapper itemParamItemMapper; @Override public String getItemParamByItemId(Long itemId) { //根據商品id查詢規格引數 TbItemParamItemExample example = new TbItemParamItemExample(); Criteria criteria = example.createCriteria(); criteria.andItemIdEqualTo(itemId); //執行查詢 List<TbItemParamItem> list = itemParamItemMapper.selectByExampleWithBLOBs(example); if (list == null || list.size() == 0) { return ""; } //取規格引數資訊 TbItemParamItem itemParamItem = list.get(0); String paramData = itemParamItem.getParamData(); //生成html // 把規格引數json資料轉換成java物件 List<Map> jsonList = JsonUtils.jsonToList(paramData, Map.class); StringBuffer sb = new StringBuffer(); sb.append("<table cellpadding=\"0\" cellspacing=\"1\" width=\"100%\" border=\"0\" class=\"Ptable\">\n"); sb.append(" <tbody>\n"); for(Map m1:jsonList) { sb.append(" <tr>\n"); sb.append(" <th class=\"tdTitle\" colspan=\"2\">"+m1.get("group")+"</th>\n"); sb.append(" </tr>\n"); List<Map> list2 = (List<Map>) m1.get("params"); for(Map m2:list2) { sb.append(" <tr>\n"); sb.append(" <td class=\"tdTitle\">"+m2.get("k")+"</td>\n"); sb.append(" <td>"+m2.get("v")+"</td>\n"); sb.append(" </tr>\n"); } } sb.append(" </tbody>\n"); sb.append("</table>"); return sb.toString(); } } |
6.3 Controller
接收商品id呼叫Service查詢規格引數資訊,得到規格引數的html。返回一個邏輯檢視。把html展示到頁面。
@Controller public class ItemParamItemController { @Autowired private ItemParamItemService itemParamItemService; @RequestMapping("/item/{itemId}") public String showItemParam(@PathVariable Long itemId, Model model) { String string = itemParamItemService.getItemParamByItemId(itemId); model.addAttribute("itemParam", string); return"item"; } } |