淘淘商城第30讲——实现商品添加功能

经过上文的学习,我相信大家都应该知道了富文本编辑器的使用方法,我们能走到这步,实属不易,本文终于可以来实现商品添加这个功能了。

在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来快速筛选出添加的商品信息描述,如下图所示。
在这里插入图片描述
这说明数据存储完全没问题。这样,我们的商品添加功能便实现了。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李阿昀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值