概述
经过上文的学习,我相信大家都应该知道了富文本编辑器的使用方法,我们能走到这步,实属不易,本文终于可以来实现商品添加这个功能了。
在item-add.jsp页面当中,当点击提交按钮后,会触发submitForm方法,如下图所示。
在咱们提交表单前还需要校验输入的内容是否合法,如下图所示。
下面我们看下数据库中商品表的建表信息,可以看到价格定义的字段类型是long型,单位为分,之所以这样做是为了避免使用小数点,因为小数点使用起来比较麻烦,因此存到数据库商品表中的价格都是价格(用户输入价格时一般都是喜欢以元为单位,难道不是这样吗?)乘以100的(变为分)。
从上图中,我们发现在商品表当中并没有商品描述这个字段,怎么会没有呢?其实商品描述是专门用一张表来存放的,如下图所示,可以看到商品描述与商品id是一一对应的,之所以把商品描述单独放到一张表当中是因为它是个大文本字段,存储的信息量会非常大,对于不需要商品描述的查询情况来说,连带这个字段查询会影响到查询效率,因此单独存放。
接下来,我们来看看表单中是如何表示的,如下图所示,可以看到有两个<input>
控件,第一个<input>
控件用来展示商品的价格,即单位为元的价格(这更符合用户的习惯),第二个<input>
控件是个隐藏域,专门用来存放以分为单位的价格(即将以元为单位的价格乘以100),表单提交时便会提交name="price"
的价格并保存到数据库表中。
当用户填写完商品详细信息后,会以Ajax的post方式提交表单,如下图所示,post方法中的第一个参数是请求的url,即/item/save
;第二个参数是$("#itemAddForm").serialize()
,它主要用于将表单的数据序列化为key-value形式的字符串。最后,如果表单提交成功后则返回200的状态码。
由于每个操作都需要有状态码(status)来表示操作成功与否以及相关信息,因此我们定义一个TaotaoResult类来专门处理,该类定义了三个属性,分别是状态、消息以及数据,由于这个类会被多个工程所使用,因此放到taotao-common工程的com.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;
}
}
/**
* 没有object对象的转化
*
* @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;
}
}
}
温馨提示:TaotaoResult类一定要实现序列化接口,很多人都会忘记哟!!!
添加商品信息和商品描述对应的都是单表操作,因此我们使用逆向工程生成的代码即可,也就是说我们不用编写dao层的代码。下面我们重点来编写service层的代码。
首先在ItemService接口当中新增一个添加商品的方法(这一个方法要操作两张表,一张是商品表,另一张是商品描述表),如下图所示,该方法的参数有两个,一个是代表商品表的pojo,另一个是商品描述。
然后我们在service层中来实现这个接口,如下图所示,我们在ItemServiceImpl实现类当中实现了addItem方法,其中商品id(也叫商品编号)是采用当前毫秒数加两位随机数来生成的,为了方便以后调用,我们专门封装了一个叫做IDUtils的工具类,里面不仅封装了商品id的生成方法而且还封装了图片名称的生成方法。由于该类会被多个工程使用,因此我们也放到taotao-common工程的com.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 tbItemMapper;
@Autowired
private TbItemDescMapper itemDescMapper;
@Override
public TbItem getItemById(Long itemId) {
TbItem item = tbItemMapper.selectByPrimaryKey(itemId);
return item;
}
@Override
public EasyUIDataGridResult getItemList(Integer page, Integer rows) {
// 1. 设置分页的信息,使用PageHelper
if (page == null) {
page = 1;
}
if (rows == null) {
rows = 30;
}
PageHelper.startPage(page, rows);
// 2. 注入Mapper
// 3. 创建一个TbItemExample对象,而且不需要设置查询条件
TbItemExample example = new TbItemExample();
// 4. 根据Mapper调用查询所有数据的方法
List<TbItem> list = tbItemMapper.selectByExample(example);
// 5. 获取分页信息
PageInfo<TbItem> info = new PageInfo<TbItem>(list);
// 6. 封装到EasyUIDataGridResult对象中并返回
EasyUIDataGridResult result = new EasyUIDataGridResult();
result.setTotal((int)info.getTotal());
result.setRows(info.getList());
return result;
}
@Override
public TaotaoResult addItem(TbItem item, String desc) {
// 生成商品id
long itemId = IDUtils.genItemId();
// 补全item对象的属性
item.setId(itemId);
// 商品状态,1:正常,2:下架,3:删除
item.setStatus((byte) 1);
item.setCreated(new Date());
item.setUpdated(new Date());
// 向商品表中插入数据
tbItemMapper.insert(item);
// 创建一个商品描述表对应的pojo
TbItemDesc itemDesc = new TbItemDesc();
// 补全pojo的属性
itemDesc.setItemId(itemId);
itemDesc.setItemDesc(desc);
itemDesc.setCreated(new Date());
itemDesc.setUpdated(new Date());
// 向商品描述表中插入数据
itemDescMapper.insert(itemDesc);
// 返回结果
return TaotaoResult.ok();
}
}
其中,IDUtils工具类的代码如下所示。
package com.taotao.common.utils;
import java.util.Random;
/**
* 各种id生成策略
* <p>Title: IDUtils</p>
* <p>Description: </p>
* <p>Company: www.itcast.com</p>
* @author 入云龙
* @date 2015年7月22日下午2:32:10
* @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层的代码。我们应在ItemController类中添加一个如下addItem方法,其中@RequestMapping("/item/save")
注解中的url请求路径是在item-add.jsp页面的js代码当中定义好的,我们要保持一致才行。
紧接着我们便来测试一下我们的商品添加功能是否好使,由于taotao-common工程以及taotao-manager工程都做了修改,因此我们需要对这两个工程重新打包,如何打包在此不再赘述。
当我们重启完taotao-manager工程和taotao-manager-web工程之后,跳转到新增商品页面,输入相关商品信息,最后点击提交
按钮。
这时,我们会发现弹出了一个提示框,提示我们商品添加成功了,添加完之后,我们到商品列表中去查询,看是否有我们刚才添加的商品,我们直接查看最后一页的数据,发现最后一条就是刚才添加的商品信息,这已说明添加商品成功了。
我们再到数据库表中看看添加的商品信息,首先查看下tb_item表,我们还是到最后一页去查看,发现有刚才添加的商品信息,如下图所示。
再查看下商品描述表,我们可通过商品id来快速筛选出添加的商品信息描述,如下图所示。
这说明数据存储完全没问题。这样,我们的商品添加功能便实现了。
最后
以上就是糊涂绿茶为你收集整理的淘淘商城第30讲——实现商品添加功能的全部内容,希望文章能够帮你解决淘淘商城第30讲——实现商品添加功能所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复