您的位置:首页 > 其它

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

2017-04-15 19:01 162 查看
      上节课我们一起学习了富文本编辑器的使用,这节课我们一起学习下商品添加的实现。

      在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 {

@Autowired
private TbItemMapper itemMapper;
@Autowired
private TbItemDescMapper itemDescMapper;

@Override
public TbItem getItemById(long itemId) {
TbItem tbItem = itemMapper.selectByPrimaryKey(itemId);
return tbItem;
}

@Override
public 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;
}

@Override
public TaotaoResult createItem(TbItem tbItem, String desc) throws Exception{
//生成商品ID
long 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){
//创建一个商品描述表对应的pojo
TbItemDesc 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);
//如果不足三位前面补0
String 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);
//如果不足两位前面补0
String 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表,我们还是到最后一页去查看,发现有我刚才添加的信息,如下图所示。



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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: