上节课我们一起学习了富文本编辑器的使用,这节课我们一起学习下商品添加的实现。

在item-add.jsp当中,当点击提交按钮后,会触发submitForm方法,如下图所示。

在提交表单前需要校验输入的内容是否合法,如下图所示。

下面我们看下数据库中商品表的建表信息,可以看到价格定义的字段类型是long型,单位为分,之所以这样做是为了避免使用小数点,因为小数点使用起来比较麻烦。因此存到数据库中的价格都是价格(以元为单位)乘以100的(变为分)。

我们发现在商品表当中没有商品描述这个字段,其实商品描述是专门用一张表来存放了,如下图所示。可以看到商品描述与商品ID是一一对应的,之所以把商品描述单独放到一张表当中是因为它是个大文本字段,存储的信息量非常大,对于不需要商品描述的查询情况来说连带这个字段查询会影响查询效率,因此单独存放。

我们看看表单中是如何表示的,如下图所示,可以看到有两个<input>组件,第一个用来展示的价格,即单位为元的价格(这更符合用户的习惯),第二个<input>是个隐藏域,专门用来存放以分为单位而的价格(即将以元为单位的价格乘以100)。表单提交便会提交name="price"的价格并保存到数据库。

提交表单会请求url为"/item/save",第二个参数$("#itemAddForm").serialize()是用来将表单的数据序列化为key-value形式的字符串。如果提交成功应该返回状态码为200。

由于每个操作都需要有状态码来表示操作成功与否以及相关信息,因此我们定义一个TaotaoResult来专门处理,该类定义三个属性,分别是状态、消息及数据。由于这个类会被多个工程所使用,因此放到taotao-common的pojo目录下。

TaotaoResult类的全部代码如下,里面最常用的便是ok方法和build方法。

package com.taotao.common.pojo;import java.io.Serializable;
import java.util.List;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;/*** 淘淘商城自定义响应结构*/
public class TaotaoResult implements Serializable{// 定义jackson对象private static final ObjectMapper MAPPER = new ObjectMapper();// 响应业务状态private Integer status;// 响应消息private String msg;// 响应中的数据private Object data;public static TaotaoResult build(Integer status, String msg, Object data) {return new TaotaoResult(status, msg, data);}public static TaotaoResult ok(Object data) {return new TaotaoResult(data);}public static TaotaoResult ok() {return new TaotaoResult(null);}public TaotaoResult() {}public static TaotaoResult build(Integer status, String msg) {return new TaotaoResult(status, msg, null);}public TaotaoResult(Integer status, String msg, Object data) {this.status = status;this.msg = msg;this.data = data;}public TaotaoResult(Object data) {this.status = 200;this.msg = "OK";this.data = data;}//    public Boolean isOK() {
//        return this.status == 200;
//    }public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}/*** 将json结果集转化为TaotaoResult对象* * @param jsonData json数据* @param clazz TaotaoResult中的object类型* @return*/public static TaotaoResult formatToPojo(String jsonData, Class<?> clazz) {try {if (clazz == null) {return MAPPER.readValue(jsonData, TaotaoResult.class);}JsonNode jsonNode = MAPPER.readTree(jsonData);JsonNode data = jsonNode.get("data");Object obj = null;if (clazz != null) {if (data.isObject()) {obj = MAPPER.readValue(data.traverse(), clazz);} else if (data.isTextual()) {obj = MAPPER.readValue(data.asText(), clazz);}}return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);} catch (Exception e) {return null;}}/*** 将json串转化为TaotaoResult对象* * @param json* @return*/public static TaotaoResult format(String json) {try {return MAPPER.readValue(json, TaotaoResult.class);} catch (Exception e) {e.printStackTrace();}return null;}/*** Object是集合转化* * @param jsonData json数据* @param clazz 集合中的类型* @return*/public static TaotaoResult formatToList(String jsonData, Class<?> clazz) {try {JsonNode jsonNode = MAPPER.readTree(jsonData);JsonNode data = jsonNode.get("data");Object obj = null;if (data.isArray() && data.size() > 0) {obj = MAPPER.readValue(data.traverse(),MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));}return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);} catch (Exception e) {return null;}}}

添加商品和商品描述对应的都是单表操作,因此我们使用逆向工程生成的代码即可,也就是说我们不用写Dao层的代码。下面我们来写Service层代码,首先在ItemService接口当中添加一个"添加商品"的接口(这一个接口要操作两张表,一张是商品表,另一张是商品描述表)。如下图所示,参数有两个,一个是商品表的pojo,另一个是商品描述。之所以要抛出异常是因为这个接口要操作两张表,而且这两张表的操作要都成功才叫成功,否则事务就回滚,因此异常要向上抛,在实现类代码中不能用try catch来捕获异常,因为这样的话springmvc会认为代码正常结束了,便不会回滚。

下面我们到service层来实现这个接口,如下图所示,我们在itemServiceImpl当中实现了createItem接口,其中商品ID(也叫商品编号)是采用当前毫秒数加两位随机数来生成的,为了方便以后调用,我们专门封装了一个类,叫IDUtils,里面不仅封装了商品ID的生成方法还封装了图片名称的生成方法,由于该类会被多个工程使用,因此我们也放到taotao-common的utils目录下。

当前ItemServiceImpl的全部代码如下

package com.taotao.service.impl;import java.util.Date;
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.IDUtils;
import com.taotao.mapper.TbItemDescMapper;
import com.taotao.mapper.TbItemMapper;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbItemDesc;
import com.taotao.pojo.TbItemExample;
import com.taotao.service.ItemService;@Service
public class ItemServiceImpl implements ItemService {@Autowiredprivate TbItemMapper itemMapper;@Autowiredprivate TbItemDescMapper itemDescMapper;@Overridepublic TbItem getItemById(long itemId) {TbItem tbItem = itemMapper.selectByPrimaryKey(itemId);return tbItem;}@Overridepublic EasyUIDataGridResult getItemList(int page, int rows) {//设置分页信息PageHelper.startPage(page, rows);//执行查询TbItemExample example = new TbItemExample();List<TbItem>  list = itemMapper.selectByExample(example);//获取查询结果PageInfo<TbItem> pageInfo = new PageInfo<>(list);EasyUIDataGridResult result = new EasyUIDataGridResult();result.setRows(list);result.setTotal(pageInfo.getTotal());//返回结果return result;}@Overridepublic TaotaoResult createItem(TbItem tbItem, String desc) throws Exception{//生成商品IDlong itemId = IDUtils.genItemId();//补全item的属性tbItem.setId(itemId);//商品状态,1-正常,2-下架,3-删除tbItem.setStatus(((byte) 1));tbItem.setCreated(new Date());tbItem.setUpdated(new Date());itemMapper.insert(tbItem);//添加商品描述insertItemDesc(itemId, desc);return TaotaoResult.ok();}//添加商品描述private void insertItemDesc(long itemId,String desc){//创建一个商品描述表对应的pojoTbItemDesc itemDesc = new TbItemDesc();//补全pojo的属性itemDesc.setItemId(itemId);itemDesc.setItemDesc(desc);itemDesc.setCreated(new Date());itemDesc.setUpdated(new Date());//向商品描述表插入数据itemDescMapper.insert(itemDesc);}}

IDUtils类的代码如下。

package com.taotao.utils;import java.util.Random;/*** 各种id生成策略* <p>Title: IDUtils</p>* <p>Description: </p>* @version 1.0*/
public class IDUtils {/*** 图片名生成*/public static String genImageName() {//取当前时间的长整形值包含毫秒long millis = System.currentTimeMillis();//long millis = System.nanoTime();//加上三位随机数Random random = new Random();int end3 = random.nextInt(999);//如果不足三位前面补0String str = millis + String.format("%03d", end3);return str;}/*** 商品id生成*/public static long genItemId() {//取当前时间的长整形值包含毫秒long millis = System.currentTimeMillis();//long millis = System.nanoTime();//加上两位随机数Random random = new Random();int end2 = random.nextInt(99);//如果不足两位前面补0String str = millis + String.format("%02d", end2);long id = new Long(str);return id;}public static void main(String[] args) {for(int i=0;i< 100;i++)System.out.println(genItemId());}
}

下面我们来写Controller层,我们在Controller层添加addItem方法,其中value="/item/save"是在list-add.jsp的js当中定义好的,我们要保持一致才行。在Controller层我们要捕获从实现类抛出的异常,避免异常直接抛到前台页面。

下面我们便来试试我们的添加商品功能是否好使,由于taotao-common工程以及taotao-manager工程都做了修改,因此我们需要对这两个工程重新打包,打包方法是在工程上右键------>Run As------>Maven install。

下面我们重启taotao-manager工程和taotao-manager-web工程,启动完工程之后,我们到新增商品页面,输入相关表单信息,然后点击"提交"按钮。

我们会发现弹出一个提示框,提示我们添加成功,添加完之后,我们到商品列表中去查询,看是否有我们刚才添加的商品,我们直接查看最后一页的数据,发现最后一条就是我刚才添加的商品信息,说明添加商品成功了。

我们再到数据库中看看添加的商品信息,首先看tb_item表,我们还是到最后一页去查看,发现有我刚才添加的信息,如下图所示。

再看商品描述表,最后一页也有我们添加的商品描述信息,这说明数据存储完全没问题。这样,我们的商品添加功能便实现了。

学习淘淘商城第二十三课(添加商品的实现)相关推荐

  1. NeHe OpenGL教程 第二十三课:球面映射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  2. OpenGL教程翻译 第二十三课 阴影贴图(一)

    第二十三课 阴影贴图(一) 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) 背景 阴影和光是紧密联系在一起的,因为如果你想要产生一个阴影就必须要光.有许多的 ...

  3. 宇宙精密调治的再思《基督教与科学》第二十三课

    黄牧师 从圣经诗19:1-2,看宇宙.太阳系.地球.生物.人类的创造. 一.回顾宇宙.地球.生物.人的设计 宇宙.地球.太阳系.行星.地球环境.生命.人,一切都有极端精密的调治,很清楚可以观察到有看不 ...

  4. Vue2+Vue3的专题目录结构(第二十三课)

    这个世界有些事情真的是无法改变的,我们唯一能做的,只是在自己与世界之间找到一个平衡点. 了解Vue框架的大致学习方向(第一课)_星辰镜的博客-CSDN博客 Vue框架的学习(Vue的基础指令操作一)第 ...

  5. Python爬虫学习笔记-第十二+十三课(selenium综合练习-12306购票)

    selenium综合练习-实现12306购票 1. 练习初衷 2. selenium实现12306购票 2.1 类基本框架 2.2 网站登录 2.3 车次以及余票查询 2.4 解析车次列表 2.5 确 ...

  6. 第二十三课.Kaggle交易预测

    目录 简介 基于 lightgbm 的 Kaggle 交易预测 baseline 优化 简介 实验基于 Kaggle 竞赛数据,使用 lightgbm 预测银行客户在未来是否会进行交易,比赛地址(已结 ...

  7. 我学习从事项目经理第二个课

    既然我想做项目经理了,也了解了项目经理的职责,任务.那我做项目经理,其实还需要知道项目经理的晋升路线才行.因为我现在还是Android开发工程师,要做项目经理不可能一下就可以做项目经理的.我需要找个导 ...

  8. 第二十三课,抗锯齿(Anti Aliasing)

    Anti Aliasing(ˈænti ,ˈeliəsɪŋ )反走样 文章目录 超采样抗锯齿(Super Sample Anti-aliasing, SSAA) 多重采样抗锯齿(Multisample ...

  9. 【线性代数公开课MIT Linear Algebra】 第二十三课 微分方程与exp(At)

    本系列笔记为方便日后自己查阅而写,更多的是个人见解,也算一种学习的复习与总结,望善始善终吧~ 一阶常系数微分方程 Au=dudt 将一阶常系数微分方程转换为线性代数问题的关键在于常系数微分方程的解一定 ...

最新文章

  1. C# DES 加密 解密
  2. WPF 路由事件初步
  3. tcp 组播_华为组播理论知识详解(二)
  4. 日志级别 debug info warn eirror fatal
  5. 关于CDC功能的答疑
  6. fast角点检测 java_opencv3_java 图像的角点检测DetectConers goodFeaturesToTrack
  7. centos7图形化界面安装KVM虚拟机
  8. 温度压力测试软件什么好,温度压力测试_鲁大师温度压力测试多少度正常
  9. 前端基础知识体系之项目经验篇
  10. sangerbox制作heapmap_ArcMap制作土地利用转移矩阵——图文详解版.pdf
  11. CRT 之LISENCE
  12. 学习《医学三字经白话解》之医学源流+中风
  13. 蚂蚁金服5面,总结了49个面试题,遇到的面试官都是P7级别以上
  14. 华为eNSP-ISIS理论+实验配置
  15. 如何将python代码封装成app_python打包成可执行文件app
  16. 可以插卡的ipad_可以插卡的ipad是几代
  17. 小程序蓝牙开发官方demo--不能发送字符串命令或发送失败10004问题
  18. Python函数判断素数并输出前五十个素数
  19. Linux中移植3G上网卡
  20. 中鑫优配热点:虚拟现实+海上风电+光伏建筑+钢铁板块

热门文章

  1. ③ESP8266 开发学习笔记_By_GYC 【虚拟机Ubuntu系统的安装】
  2. telerik学习记录-RadButton(上)
  3. FISCO BCOS 联盟链Max搭建
  4. 如何编辑出一篇漂亮的微信公众号文章
  5. 带建筑物的点云到 3D地形模型
  6. 网易开源游戏服务器框架-Pomelo实践(一)
  7. 淘宝特价版上货精灵有哪些功能特点?
  8. java 中的哈希码
  9. gbase 导出_gbase 通过 gccli 命令客户端导出数据到文件
  10. arduino编乐谱_把乐谱播出来,自制简谱播放库