校园商铺-8商品模块-12接触商品与某商品类别的关联的实现
去删除productCategory时,由于商品类别与商品建立了联系,在删除商品列别之前,需要将商品里的productCategoryId置为空。
1.Dao层
1.接口
package com.csj2018.o2o.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.csj2018.o2o.entity.Product;
public interface ProductDao {
/**
* 8-10查询商品列表并分页,可输入的条件有:商品名(模糊)、商品状态,店铺ID,商品类别
* @param productCondition
* @param beginIndex
* @param pageSize
* @return
*/
List<Product> queryProductList(@Param("productCondition") Product productCondition, @Param("rowIndex") int rowIndex, @Param("pageSize") int pageSize);
/**
* 8-10查询对应的商品总数
* @param productCondition
* @return
*/
int queryProductCount(@Param("productCondition") Product productCondition);
Product queryProductById(Long productId);
/**
* 插入商品
* @param product
* @return
*/
int insertProduct(Product product);
/**
* 更新商品信息
* @param product
* @return
*/
int updateProduct(Product product);
/**
* 8-11删除商品类别之前,将商品类别ID置为空
* @param productCategoryId
* @return
*/
int updateProductCategoryToNull(Long productCategoryId);
int deleteProduct(Product product);
}
2.实现类
<?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.csj2018.o2o.dao.ProductDao"><!-- 对应接口类名 -->
<resultMap id="productMap" type="com.csj2018.o2o.entity.Product">
<id column="product_id" property="productId" />
<result column="product_name" property="productName" />
<result column="product_desc" property="productDesc" />
<result column="img_addr" property="imgAddr" />
<result column="normal_price" property="normalPrice" />
<result column="promotion_price" property="promotionPrice" />
<result column="priority" property="priority" />
<result column="create_time" property="createTime" />
<result column="last_edit_time" property="lastEditTime" />
<result column="enable_status" property="enableStatus" />
<association property="productCategory" column="product_category_id" javaType="com.csj2018.o2o.entity.ProductCategory">
<id column="product_category_id" property="productCategoryId" />
<result column="product_category_name" property="productCategoryName" />
</association>
<association property="shop" column="shop_id" javaType="com.csj2018.o2o.entity.Shop">
<id column="shop_id" property="shopId" />
<result column="shop_id" property="shopId" />
</association>
<collection property="productImgList" column="product_id" ofType="com.csj2018.o2o.entity.ProductImg">
<id column="product_img_id" property="productImgId" />
<result column="detail_img" property="imgAddr" /><!-- 有疑问,为什么不是img_addr -->
<result column="img_desc" property="imgDesc" />
<result column="priority" property="priority" />
<result column="create_time" property="createTime" />
<result column="product_id" property="productId" />
</collection>
</resultMap>
<select id="queryProductById" resultMap="productMap" parameterType="long">
select
p.product_id, p.product_name, p.product_desc, p.img_addr, p.normal_price, p.promotion_price, p.priority,
p.create_time, p.last_edit_time, p.enable_status, p.product_category_id, p.shop_id,
pm.product_img_id, pm.img_addr as detail_img, pm.img_desc, pm.priority, pm.create_time
from tb_product p left join tb_product_img pm
on p.product_id = pm.product_id
where p.product_id = #{productId}
order by pm.priority desc
</select>
<update id="updateProduct" parameterType="com.csj2018.o2o.entity.Product" keyProperty="product_id" useGeneratedKeys="true">
update tb_product
<set>
<if test="productName != null">product_name = #{productName},</if>
<if test="productDesc != null">product_desc = #{productDesc},</if>
<if test="imgAddr != null">img_addr = #{imgAddr},</if>
<if test="normalPrice != null" >normal_price = #{normalPrice},</if>
<if test="promotionPrice != null">promotion_price = #{promotionPrice},</if>
<if test="priority != null">priority = #{priority},</if>
<if test="lastEditTime != null">last_edit_time = #{lastEditTime},</if>
<if test="enableStatus != null">enable_status = #{enableStatus},</if>
<if test="productCategory != null and productCategory.productCategoryId != null">product_category_id = #{productCategory.productCategoryId}</if>
</set>
where product_id = #{productId} and shop_id = #{shop.shopId}<!--shop_id = #{shop.shopId}保证了不会操作别的店铺的商品 -->
</update>
<insert id="insertProduct" parameterType="com.csj2018.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>
<select id="queryProductList" resultType="com.csj2018.o2o.entity.Product">
select
product_id, product_name, product_desc, img_addr,
normal_price, promotion_price, priority, create_time,
last_edit_time, enable_status, product_category_id, shop_id
from tb_product
<where>
<if test="productCondition.shop != null and productCondition.shop.shopId != null">
and shop_id = #{productCondition.shop.shopId}
</if>
<if test="productCondition.productCategory != null and productCondition.productCategory.productCategoryId != null">
and product_category_id = #{productCondition.productCategory.productCategoryId}
</if>
<!-- 写like语句的时候 一般都会写成like '% %',在mybatis里面写就是like '%${name}%',而不是like '%#{name}%'。${name}是不带单引号的,#{name}是带单引号的。-->
<if test="productCondition.productName != null ">
and product_name like '%${productCondition.productName}%'
</if>
<if test="productCondition.enableStatus != null">
and enable_status = #{productCondition.enableStatus}
</if>
</where>
order by priority desc limit #{rowIndex},#{pageSize};
</select>
<select id="queryProductCount" resultType="int">
select count(1) from tb_product
<where>
<if test="productCondition.shop != null and productCondition.shop.shopId != null">
and shop_id = #{productCondition.shop.shopId}
</if>
<if test="productCondition.productCategory != null and productCondition.productCategory.productCategoryId != null">
and product_category_id = #{productCondition.productCategory.productCategoryId}
</if>
<!-- 写like语句的时候 一般都会写成like '% %',在mybatis里面写就是like '%${name}%',而不是like '%#{name}%'。${name}是不带单引号的,#{name}是带单引号的。-->
<if test="productCondition.productName != null">
and product_name like '%${productCondition.productName}%'
</if>
<if test="productCondition.enableStatus != null">
and enable_status = #{productCondition.enableStatus}
</if>
</where>
</select>
<!-- 8-11 -->
<update id="updateProductCategoryToNull" parameterType="Long">
update tb_product set product_category_id = null where product_category_id = #{productCategoryId}
</update>
<delete id="deleteProduct">
delete from tb_product where product_id = #{productId} and shop_id = #{shopId}
</delete>
</mapper>
3.单元测试
package com.csj2018.o2o.dao;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.junit.FixMethodOrder;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import com.csj2018.o2o.BaseTest;
import com.csj2018.o2o.entity.Product;
import com.csj2018.o2o.entity.ProductCategory;
import com.csj2018.o2o.entity.ProductImg;
import com.csj2018.o2o.entity.Shop;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ProductDaoTest extends BaseTest{
@Autowired
private ProductDao productDao;
@Autowired
private ProductImgDao productImgDao;
@Test
@Ignore
public void testAInsertProduct() throws Exception{
Shop shop1 = new Shop();
shop1.setShopId(1L);
ProductCategory pc1 = new ProductCategory();
pc1.setProductCategoryId(10L);
Product product1 = new Product();
product1.setProductName("商品1");
product1.setProductDesc("商品1的描述");
product1.setImgAddr("商品1的缩略图");
product1.setPriority(1);
product1.setEnableStatus(1);
product1.setCreateTime(new Date());
product1.setLastEditTime(new Date());
product1.setShop(shop1);
product1.setProductCategory(pc1);
Product product2 = new Product();
product2.setProductName("商品2");
product2.setProductDesc("商品2的描述");
product2.setImgAddr("商品2的缩略图");
product2.setPriority(2);
product2.setEnableStatus(0);
product2.setCreateTime(new Date());
product2.setLastEditTime(new Date());
product2.setShop(shop1);
product2.setProductCategory(pc1);
Product product3 = new Product();
product3.setProductName("商品3");
product3.setProductDesc("商品3的描述");
product3.setImgAddr("商品3的缩略图");
product3.setPriority(3);
product3.setEnableStatus(1);
product3.setCreateTime(new Date());
product3.setLastEditTime(new Date());
product3.setShop(shop1);
product3.setProductCategory(pc1);
int effectedNum = productDao.insertProduct(product1);
assertEquals(1,effectedNum);
effectedNum = productDao.insertProduct(product2);
assertEquals(1,effectedNum);
effectedNum = productDao.insertProduct(product3);
assertEquals(1,effectedNum);
}
//8-10
@Test
@Ignore
public void testBQueryProductList() {
//product表原有9条数据,商品名包含测试的有1条
Product productCondition = new Product();
//分页查询,预期返回3条数据
List<Product> productList = productDao.queryProductList(productCondition, 0, 3);
assertEquals(3,productList.size());
int count = productDao.queryProductCount(productCondition);
assertEquals(9,count);
//查询名称为测试的商品总数
productCondition.setProductName("测试");
productList = productDao.queryProductList(productCondition, 0, 3);
count = productDao.queryProductCount(productCondition);
assertEquals(1,count);
}
@Test
@Ignore
public void testCQueryProductByProductId() throws Exception{
long productId = 1;
//初始化两个商品详情图实例,作为productId为1的商品下的详情图片
//批量插入到商品详情图标中
ProductImg productImg1 = new ProductImg();
productImg1.setImgAddr("图片1");
productImg1.setImgDesc("测试图片1");
productImg1.setPriority(1);
productImg1.setCreateTime(new Date());
productImg1.setProductId(productId);
ProductImg productImg2 = new ProductImg();
productImg2.setImgAddr("图片1");
productImg2.setImgDesc("测试图片1");
productImg2.setPriority(1);
productImg2.setCreateTime(new Date());
productImg2.setProductId(productId);
List<ProductImg> productImgList = new ArrayList<>();
productImgList.add(productImg1);
productImgList.add(productImg2);
int effectedNum = productImgDao.batchInsertProductImg(productImgList);
assertEquals(2,effectedNum);
//查询productId为1的商品信息并校验返回的详情图实例列表size是否为2
Product product = productDao.queryProductById(productId);
assertEquals(2,product.getProductImgList().size());
//删除新增的这两个商品详情图示例,形成闭环
effectedNum = productImgDao.deleteProductImgByProductId(productId);
assertEquals(2,effectedNum);
}
@Test
@Ignore
public void testDUpdateProduct() {
Product product = new Product();
ProductCategory pc = new ProductCategory();
Shop shop = new Shop();
shop.setShopId(1L);
pc.setProductCategoryId(12L);
product.setProductId(1L);
product.setShop(shop);
product.setProductCategory(pc);
product.setProductName("躺着喝的美式咖啡");
int effectedNum = productDao.updateProduct(product);
assertEquals(1,effectedNum);
}
//8-11
@Test
// @Ignore
public void testEUpdateProductCategoryToNull() {
//将productCategoryId为2的商品类别下面的商品的商品类别置为空
int effectNum = productDao.updateProductCategoryToNull(12L);
assertEquals(effectNum,1);
}
@Test
@Ignore
public void testFDeleteShopAutoMap() {}
}
2. Service层
package com.csj2018.o2o.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.csj2018.o2o.dao.ProductCategoryDao;
import com.csj2018.o2o.dao.ProductDao;
import com.csj2018.o2o.dto.ProductCategoryExecution;
import com.csj2018.o2o.entity.ProductCategory;
import com.csj2018.o2o.enums.ProductCategoryStateEnum;
import com.csj2018.o2o.exceptions.ProductCategoryOperationException;
import com.csj2018.o2o.service.ProductCategoryService;
@Service
public class ProductCategoryServiceImpl implements ProductCategoryService{
@Autowired
private ProductCategoryDao productCategoryDao;
@Autowired
private ProductDao productDao;
@Override
public List<ProductCategory> getProductCategoryList(long shopId) {
// TODO Auto-generated method stub
return productCategoryDao.queryProductCategoryList(shopId);
}
//7.3增加
@Override
@Transactional
public ProductCategoryExecution batchAddProductCategory(List<ProductCategory> productCategoryList)
throws ProductCategoryOperationException {
if(productCategoryList != null && productCategoryList.size() >0) {
try {
int effectedNum = productCategoryDao.batchInsertProductCategory(productCategoryList);
if(effectedNum <= 0) {
throw new ProductCategoryOperationException("店铺类别创建失败");
}else {
return new ProductCategoryExecution(ProductCategoryStateEnum.SUCCESS);
}
}catch (Exception e) {
throw new ProductCategoryOperationException("batchAddProductCategory error:" + e.getMessage());
}
}else {
return new ProductCategoryExecution(ProductCategoryStateEnum.EMPTY_LIST);
}
}
//7-5
@Override
public ProductCategoryExecution deleteProductCategory(long productCategoryId, long shopId)
throws ProductCategoryOperationException {
// 8-11将该类别下的商品类别置为空
try {
int effectedNum = productDao.updateProductCategoryToNull(productCategoryId);
if(effectedNum <0) {
throw new ProductCategoryOperationException("商品类别更新失败");
}
}catch(Exception e) {
throw new ProductCategoryOperationException("deleteProductCategory error:"+e.getMessage());
}
try {
int effectedNum = productCategoryDao.deleteProductCategory(productCategoryId, shopId);
if(effectedNum <= 0) {
throw new ProductCategoryOperationException("商品类别删除失败");
}else {
return new ProductCategoryExecution(ProductCategoryStateEnum.SUCCESS);
}
}catch(Exception e) {
throw new ProductCategoryOperationException("delete ProductCategory error:"+e.getMessage());
}
}
}