商品添加之Dao层的实现
ProductDao
/**
* 插入商品
*
* @param product
* @return
*/
int insertProduct(Product product);
ProductDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.o2o.dao.ProductDao">
<insert id="insertProduct" parameterType="com.imooc.o2o.entity.Product"
useGeneratedKeys="true" keyProperty="productId" keyColumn="product_id">
INSERT INTO
tb_product(product_name,product_desc,img_addr,
normal_price,promotion_price,priority,create_time,
last_edit_time,enable_status,product_category_id,
shop_id)
VALUES
(#{productName},#{productDesc},#{imgAddr},
#{normalPrice},#{promotionPrice},#{priority},#{createTime},
#{lastEditTime},#{enableStatus},#{productCategory.productCategoryId},
#{shop.shopId})
</insert>
</mapper>
ProductImgDao.xml
package com.imooc.o2o.dao;
import com.imooc.o2o.entity.ProductImg;
import java.util.List;
public interface ProductImgDao {
List<ProductImg> queryProductImgList(long productId);
int batchInsertProductImg(List<ProductImg> productImgList);
int deleteProductImgByProductId(long productId);
}
ProductImgDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.o2o.dao.ProductImgDao">
<select id="queryProductImgList" resultType="com.imooc.o2o.entity.ProductImg">
select
product_img_id,
img_addr,
img_desc,
priority,
create_time,
product_id
from tb_product_img
where product_id=#{productId}
order by
product_img_id asc
</select>
<insert id="batchInsertProductImg" parameterType="java.util.List">
insert into
tb_product_img(img_addr,img_desc,priority,create_time,product_id)
values
<foreach collection="list" item="productImg" index="index"
separator=",">
(
#{productImg.imgAddr},
#{productImg.imgDesc},
#{productImg.priority},
#{productImg.createTime},
#{productImg.productId}
)
</foreach>
</insert>
<delete id="deleteProductImgByProductId">
delete from
tb_product_img
where
product_id=#{productId}
</delete>
</mapper>
测试
package com.imooc.o2o.dao;
import com.imooc.o2o.BaseTest;
import com.imooc.o2o.entity.ProductImg;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.junit.Assert.*;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ProductImgDaoTest extends BaseTest {
@Autowired
private ProductImgDao productImgDao;
@Test
public void BqueryProductImgList() {
List<ProductImg> productImgList = new ArrayList<ProductImg>();
productImgList=productImgDao.queryProductImgList(1);
for (ProductImg productImg:productImgList){
System.out.println(productImg.getImgDesc());
}
}
@Test
public void AbatchInsertProductImg() {
ProductImg productImg1 = new ProductImg();
productImg1.setImgAddr("图片1");
productImg1.setImgDesc("测试图片1");
productImg1.setPriority(1);
productImg1.setCreateTime(new Date());
productImg1.setProductId(1L);
ProductImg productImg2 = new ProductImg();
productImg2.setImgAddr("图片2");
productImg2.setImgDesc("测试图片2");
productImg2.setPriority(1);
productImg2.setCreateTime(new Date());
productImg2.setProductId(1L);
List<ProductImg> productImgList = new ArrayList<ProductImg>();
productImgList.add(productImg1);
productImgList.add(productImg2);
int effectedNum=productImgDao.batchInsertProductImg(productImgList);
assertEquals(2,effectedNum);
}
@Test
public void CdeleteProductImgByProductId() {
long productId=1;
int effectedNum = productImgDao.deleteProductImgByProductId(productId);
assertEquals(2,effectedNum);
}
}
商品添加之Service层实现
ProductService
package com.imooc.o2o.service;
import com.imooc.o2o.dto.ImageHolder;
import com.imooc.o2o.dto.ProductExecution;
import com.imooc.o2o.entity.Product;
import com.imooc.o2o.exceptions.ProductOperationException;
import java.io.InputStream;
import java.util.List;
public interface ProductService {
// ProductExecution addProduct(Product product, InputStream thumbnail,
// String thumbnailName,
// List<InputStream> productImgList,
// List<String> productImgNameList) throws ProductOperationException;
ProductExecution addProduct(Product product, ImageHolder thumbnail,
List<ImageHolder> productImgList) throws ProductOperationException;
}
在dto中创建ImageHolder,并将之前涉及到店铺信息图片上传的代码重构
package com.imooc.o2o.dto;
import java.io.InputStream;
public class ImageHolder {
private String imageName;
private InputStream image;
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
public InputStream getImage() {
return image;
}
public void setImage(InputStream image) {
this.image = image;
}
public ImageHolder(String imageName, InputStream image) {
this.imageName = imageName;
this.image = image;
}
}
ProductServiceImpl
package com.imooc.o2o.service.impl;
import com.imooc.o2o.dao.ProductDao;
import com.imooc.o2o.dao.ProductImgDao;
import com.imooc.o2o.dto.ImageHolder;
import com.imooc.o2o.dto.ProductExecution;
import com.imooc.o2o.entity.Product;
import com.imooc.o2o.entity.ProductImg;
import com.imooc.o2o.enums.ProductStateEnum;
import com.imooc.o2o.exceptions.ProductOperationException;
import com.imooc.o2o.service.ProductService;
import com.imooc.o2o.util.ImageUtil;
import com.imooc.o2o.util.PathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductDao productedao;
@Autowired
private ProductImgDao productImgDao;
@Override
@Transactional
//1.处理缩略图
//2.往tb_product写入商品信息,获取productId
//3.结合productId批量处理商品详情图
//4.将商品详情图列表批量插入tb_product_img中
public ProductExecution addProduct(Product product, ImageHolder thumbnail, List<ImageHolder> productImgList) throws ProductOperationException {
//空值判断
if(product!=null&&product.getShop()!=null&&product.getShop().getShopId()!=null){
//给商品设置上默认属性
product.setCreateTime(new Date());
product.setLastEditTime(new Date());
//默认为上架状态
product.setEnableStatus(1);
//若商品缩略图不为空则添加
if(thumbnail!=null){
addThumbnail(product,thumbnail);
}
try{
//创建商品信息
int effectedNum = productedao.insertProduct(product);
if(effectedNum<=0){
throw new ProductOperationException("创建商品失败");
}
}catch (Exception e){
throw new ProductOperationException("创建商品失败:"+e.toString());
}
//若商品详情图不为空则添加
if(productImgList!=null&&productImgList.size()>0){
addProductImgList(product,productImgList);
}
return new ProductExecution(ProductStateEnum.SUCCESS,product);
}else{
//传参为空则返回空值错误信息
return new ProductExecution(ProductStateEnum.EMPTY);
}
}
/**
* 添加缩略图
*/
public void addThumbnail(Product product,ImageHolder thumbnail){
String dest= PathUtil.getShopImagePath(product.getShop().getShopId());
String thumbnailAddr = ImageUtil.generateThumbnail(thumbnail,dest);
product.setImgAddr(thumbnailAddr);
}
/**
* 批量添加图片
*/
private void addProductImgList(Product product,
List<ImageHolder> productImgHolderList){
//获取图片存储路径,这里直接存放到相应店铺的文件夹底下
String dest= PathUtil.getShopImagePath(product.getShop().getShopId());
List<ProductImg> productImgList = new ArrayList<ProductImg>();
//遍历图片一次去处理,并添加进productImg实体类中
for(ImageHolder productImgHolder:productImgHolderList){
String imgAddr = ImageUtil.generateNormalImg(productImgHolder,dest);
ProductImg productImg = new ProductImg();
productImg.setImgAddr(imgAddr);
productImg.setProductId(product.getProductId());
productImg.setCreateTime(new Date());
productImgList.add(productImg);
}
//如果确实是有图片需要添加的,就执行批量添加操作
if(productImgList.size()>0){
try {
int effectedNum =
productImgDao.batchInsertProductImg(productImgList);
if(effectedNum<=0){
throw new ProductOperationException("创建商品详情图片失败");
}
} catch (ProductOperationException e) {
throw new ProductOperationException("创建商品详情图片失败"+e.toString());
}
}
}
}
PeoductExecution
package com.imooc.o2o.dto;
import com.imooc.o2o.entity.Product;
import com.imooc.o2o.enums.ProductStateEnum;
import java.util.List;
public class ProductExecution {
//结果状态
private int state;
//商品数量
private String stateInfo;
//操作的product(增删改查商品的时候用)
private Product product;
//获取的product列表(查询商品列表的时候用)
private List<Product> productList;
public ProductExecution(){
}
// 失败的构造器
public ProductExecution(ProductStateEnum stateEnum) {
this.state = stateEnum.getState();
this.stateInfo = stateEnum.getStateInfo();
}
public ProductExecution(ProductStateEnum stateEnum, Product product){
this.state = stateEnum.getState();
this.stateInfo = stateEnum.getStateInfo();
this.stateInfo = stateEnum.getStateInfo();
this.product =product;
}
public ProductExecution(ProductStateEnum stateEnum,
List<Product> productList){
this.state=stateEnum.getState();
this.stateInfo=stateEnum.getStateInfo();
this.productList=productList;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getStateInfo() {
return stateInfo;
}
public void setStateInfo(String stateInfo) {
this.stateInfo = stateInfo;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public List<Product> getProductList() {
return productList;
}
public void setProductList(List<Product> productList) {
this.productList = productList;
}
}
ProductOperationException
package com.imooc.o2o.exceptions;
public class ProductOperationException extends RuntimeException{
private static final long serialVersionUID = 5076172298827469013L;
public ProductOperationException(String msg) {
super(msg);
}
}
ImageUtil中的generateNormalImag
public static String generateNormalImg(ImageHolder thumbnail, String targetAddr) {
String realFileName = getRandomFileName();
//获取文件的扩展名
String extension = getFileExtension(thumbnail.getImageName());
//如果目标路径不存在则自动创建
makeDirPath(targetAddr);
//获取文件存储的相对路径
String relativeAddr = targetAddr + realFileName + extension;
//获取文件要保存到的目标路径
File dest = new File(getImgBasePath() + relativeAddr);
//调用Thumbnails生成图片
try {
Thumbnails.of(thumbnail.getImage()).size(337, 640).outputQuality(0.5f).toFile(dest);
} catch (IOException e) {
throw new RuntimeException("创建缩略图失败:" + e.toString());
}
//返回图片的相对路径
return relativeAddr;
}
商品添加之Controller层的设计
package com.imooc.o2o.web.shopadmin;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.o2o.dto.ImageHolder;
import com.imo