- 商品數據表
create table 'mmall_product'(
'id' int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id',
'category_id' int(11) NOT NULL COMMENT '分類id,對應mmal_category分類表的主鍵',
'name' varchar(100) NOT NULL COMMENT '商品名稱',
'subtitle' varchar(200) DEFAULT NULL COMMENT '商品副標題',
'main_image' varchar(500) DEFAULT NULL COMMENT '產品主圖,url相對地址',
'sub_images' text COMMENT '圖片地址,json格式,擴展用',
'detail' text COMMENT '商品詳情',
'price' decimal(20,2) NOT NULL COMMENT '價格,單位-元保留兩位小數',
'stock' int(11) NOT NULL COMMENT '庫存數量',
'status int(6) DEFAULT '1' COMMENT '商品狀態:1-在售,2-下架,3-刪除',
'create_time' datetime DEFAULT NULL COMMENT '創建時間',
'update_time' datetime DEFAULT NULL COMMENT '更新時間',
PRIMARY KEY ('id')
)ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8
- 設置公共常量類
//設置公共量
public class Const {
public static final String CURRENT_USER = "currentUser";
public static final String EMAIL="email";
public static final String USERNAME="username";
public interface Role{
int ROLE_CUSTOMER=0;//普通用戶
int ROLE_ADMIN=1;//管理員
}
}
一、增加與修改商品
- 思路:
1、判斷商品是否有圖片,如果有就用String[ ] subImagArray = product.getSubImages().split(",")以逗號分割存進數組裏,然後取數組的第一個值作爲主圖。
2、判斷傳來的id是否爲空,不爲空則進行更新操作,爲空則進行增加操作。
- controller(參數Product)
//增加商品和修改商品
//新增商品http://localhost:8080/manage/product/save.do?categoryId=1&name=三星洗衣機&subtitle=三星大促銷&subImages=test.jpg,11.jpg,2.jpg,3.jpg&detail=detailtext&price=1000&stock=100&status=1
//修改商品 http://localhost:8080/manage/product/save.do?id=3&categoryId=1&name=三星洗衣機&subtitle=三星大促銷&subImages=test.jpg&detail=detailtext&price=1000&stock=100&status=1
@RequestMapping("save.do")
@ResponseBody
public ServerResponse productSave(HttpSession session, Product product) {
User user = (User) session.getAttribute(Const.CURRENT_USER);
if (user == null) {
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用戶未登錄,請登錄管理員");
}
if (iUserService.checkAdminRole(user).isSuccess()) {
return iProductService.saveOrUpdateProduct(product);
} else {
return ServerResponse.createByErrorMessage("不是管理員,無權限操作");
}
}
- Impl(參數Product)
public ServerResponse saveOrUpdateProduct(Product product) {
if (product != null) {
//判斷商品的圖片是否爲空
if (org.apache.commons.lang3.StringUtils.isNotBlank(product.getSubImages())) {
//不爲空則把傳過來的商品圖片地址用逗號進行分割
String[] subImagArray = product.getSubImages().split(",");
if (subImagArray.length > 0) {
//取第一個商品的圖片當做主圖
product.setMainImage(subImagArray[0]);
}
}
//如果傳過來的id不爲空,則對商品進行修改更新操作
if (product.getId() != null) {
int rowCount = productMapper.updateByPrimaryKey(product);
if (rowCount > 0) {
return ServerResponse.createBySuccess("修改商品成功");
}
return ServerResponse.createByErrorMessage("修改商品失敗");
} else {
//否則進行增加商品操作
int rowCount = productMapper.insert(product);
if (rowCount > 0) {
return ServerResponse.createBySuccess("增加商品成功");
}
return ServerResponse.createByErrorMessage("增加商品失敗");
}
}
return ServerResponse.createByErrorMessage("新增或修改商品參數不正確");
}
二、商品上下架
- 思路:從前臺獲取修改的商品id與商品上下架狀態對數據庫進行修改
- controller(參數:商品id,商品狀態status)
//設置商品上下架(是否在售)
//http://localhost:8080/manage/product/set_sale_status.do?productId=1&status=1
@RequestMapping("set_sale_status.do")
@ResponseBody
public ServerResponse set_sale_status(HttpSession session, Integer productId, Integer status) {
User user = (User) session.getAttribute(Const.CURRENT_USER);
if (user == null) {
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用戶未登錄,請登錄管理員");
}
if (iUserService.checkAdminRole(user).isSuccess()) {
return iProductService.set_sale_status(productId, status);
} else {
return ServerResponse.createByErrorMessage("不是管理員,無權限操作");
}
}
- impl(參數:商品id,商品狀態status)
//商品上下架
public ServerResponse set_sale_status(Integer productId, Integer status) {
if (productId == null || status == null) {
return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDesc());
}
int rowCount = productMapper.updateBySaleStatus(productId,status);
if (rowCount > 0) {
return ServerResponse.createBySuccess("修改產品狀態成功");
}
return ServerResponse.createByErrorMessage("修改產品狀態失敗");
}
三、商品詳情
- 思路:根據商品id查找出該商品,把它加到Vo類中,由Vo類展示到前端上。
- controller(參數:商品id)
//獲取商品詳情
@RequestMapping("detail.do")
@ResponseBody
public ServerResponse getDetail(HttpSession session, Integer productId) {
User user = (User) session.getAttribute(Const.CURRENT_USER);
if (user == null) {
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用戶未登錄,請登錄管理員");
}
if (iUserService.checkAdminRole(user).isSuccess()) {
return iProductService.manageProductDetail(productId);
} else {
return ServerResponse.createByErrorMessage("不是管理員,無權限操作");
}
}
- impl(參數:商品id)
//後臺管理員獲取商品詳情
public ServerResponse<ProductDetailVo> manageProductDetail(Integer productId){
if (productId == null){
return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDesc());
}
//根據id查找出該商品
Product product=productMapper.selectByPrimaryKey(productId);
if (product == null){
return ServerResponse.createByErrorMessage("商品已下架或者刪除");
}
ProductDetailVo productDetailVo=assembleProductDetailVo(product);
return ServerResponse.createBySuccess(productDetailVo);
}
private ProductDetailVo assembleProductDetailVo(Product product){
ProductDetailVo productDetailVo = new ProductDetailVo();
productDetailVo.setId(product.getId());
productDetailVo.setSubtitle(product.getSubtitle());
productDetailVo.setPrice(product.getPrice());
productDetailVo.setMainImage(product.getMainImage());
productDetailVo.setSubImages(product.getSubImages());
productDetailVo.setCategoryId(product.getCategoryId());
productDetailVo.setDetail(product.getDetail());
productDetailVo.setName(product.getName());
productDetailVo.setStatus(product.getStatus());
productDetailVo.setStock(product.getStock());
//賦值imageHost,從配置文件中獲取圖片的前綴
productDetailVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix","http://image.mmall.com/"));
//找出該商品的父節點商品
Category category=categoryMapper.selectByPrimaryKey(product.getCategoryId());
//爲空則默認爲根節點
if (category == null){
productDetailVo.setParentCategoryId(0);
}else {
productDetailVo.setParentCategoryId(category.getParentId());
}
productDetailVo.setCreateTime(DateTimeUtil.dateToStr(product.getCreateTime()));
productDetailVo.setUpdateTime(DateTimeUtil.dateToStr(product.getUpdateTime()));
return productDetailVo;
}
四、商品列表
- 思路:
1、使用Mybatis三劍客中的PageHelper,原理是通過spring的AOP來實現的,這個插件能在執行sql的時候把sql攔截,再對sql語句進行重寫執行。使用步驟:
(1)設置起始頁:PageHelper.startPage(起始的頁數,每頁展示的數量);
(2)查詢語句:List<Product> productList=productMapper.selectList();
(3)封裝查詢的頁數:PageInfo pageInfo=new PageInfo(productList);
2、把查詢的數據用pageInfo.setList(productListVoList)轉換成Vo類展示在前端上。
- controller(參數:起始頁pageNum,每頁顯示的數量pageSize)
//商品列表
@RequestMapping("list.do")
@ResponseBody
public ServerResponse getList(HttpSession session, @RequestParam(value = "pageNum", defaultValue = "1") int pageNum, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
User user = (User) session.getAttribute(Const.CURRENT_USER);
if (user == null) {
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用戶未登錄,請登錄管理員");
}
if (iUserService.checkAdminRole(user).isSuccess()) {
return iProductService.getProductList(pageNum, pageSize);
} else {
return ServerResponse.createByErrorMessage("不是管理員,無權限操作");
}
}
- impl(參數:起始頁pageNum,每頁顯示的數量pageSize)
//商品列表
public ServerResponse<PageInfo> getProductList(int pageNum,int pageSize){
//設置起始頁數和每頁顯示的數量
PageHelper.startPage(pageNum,pageSize);
//進行分頁查詢
List<Product> productList=productMapper.selectList();
List<ProductListVo> productListVoList= Lists.newArrayList();
//查詢到的商品賦值給Vo
for (Product productItem : productList) {
ProductListVo productListVo = assembleProductListVo(productItem);
productListVoList.add(productListVo);
}
//用pageInfo包裝pojo類List的查詢結果,pageInfo封裝了pojo分頁的詳細信息
PageInfo pageInfo=new PageInfo(productList);
//pojo類的productList和VO類的productListVoList分頁參數是一致的,所以最後進行轉換成VO,展示在前端上
pageInfo.setList(productListVoList);
return ServerResponse.createBySuccess(pageInfo);
}
//每查詢出一個商品,就把商品的信息賦值給Vo,用於數據展示在前端上
private ProductListVo assembleProductListVo(Product product){
ProductListVo productListVo=new ProductListVo();
productListVo.setId(product.getId());
productListVo.setName(product.getName());
productListVo.setCategoryId(product.getCategoryId());
productListVo.setSubtitle(product.getSubtitle());
productListVo.setPrice(product.getPrice());
productListVo.setMainImage(product.getMainImage());
productListVo.setStatus(product.getStatus());
productListVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix","http://image.mmall.com/"));
return productListVo;
}
五、商品搜索(根據商品名稱或者商品ID進行搜索)
- 思路:
1、通過PageHelper設置起始頁和每頁顯示的數量。
2、判斷從前端傳來的商品名是否爲空,不爲空則用append拼接%+商品名+%進行模糊查詢。
3、通過Mybatis的SQL語句if分別判斷進行商品名和商品id不爲空的操作。
4、通過PageInfo設置Vo類展示在前端上。
- controller(參數:商品名,商品id,起始頁pageNum,每頁顯示的數量pageSize)
//商品搜索
//根據商品名稱或者商品ID進行搜索
@RequestMapping("search.do")
@ResponseBody
public ServerResponse ProductSearch(HttpSession session, String productName,Integer productId, @RequestParam(value = "pageNum", defaultValue = "1") int pageNum, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
User user = (User) session.getAttribute(Const.CURRENT_USER);
if (user == null) {
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用戶未登錄,請登錄管理員");
}
if (iUserService.checkAdminRole(user).isSuccess()) {
return iProductService.searchProduct(productName, productId, pageNum, pageSize);
} else {
return ServerResponse.createByErrorMessage("不是管理員,無權限操作");
}
}
- impl(參數:商品名,商品id,起始頁pageNum,每頁顯示的數量pageSize)
//後臺商品搜索
//pageHelper分頁主要是通過aop來實現,在執行sql之前會在sql語句中添加limit offset這兩個參數。這樣就完成了動態的分頁。
public ServerResponse<PageInfo> searchProduct(String productName,Integer productId,int pageNum,int pageSize) {
//設置起始頁和每頁顯示到的數量
PageHelper.startPage(pageNum, pageSize);
//商品名不爲空
if (StringUtils.isNotBlank(productName)) {
// %名稱%,用於拼接在like後面進行模糊查詢
productName = new StringBuilder().append("%").append(productName).append("%").toString();
}
//根據名稱或者id查找到的商品用List進行存儲
List<Product> productList = productMapper.selectByNameAndProductId(productName, productId);
//foreach循環,賦值給用於前端展示的VO類
List<ProductListVo> productListVoList = Lists.newArrayList();
for (Product productItem : productList) {
ProductListVo productListVo = assembleProductListVo(productItem);
productListVoList.add(productListVo);
}
//用pageInfo包裝pojo類List的查詢結果,pageInfo封裝了pojo分頁的詳細信息
PageInfo pageInfo = new PageInfo(productList);
//pojo類的productList和VO類的productListVoList分頁參數是一致的,所以最後進行轉換成VO,展示在前端上
pageInfo.setList(productListVoList);
return ServerResponse.createBySuccess(pageInfo);
}
//每查詢出一個商品,就把商品的信息賦值給Vo,用於數據展示在前端上
private ProductListVo assembleProductListVo(Product product){
ProductListVo productListVo=new ProductListVo();
productListVo.setId(product.getId());
productListVo.setName(product.getName());
productListVo.setCategoryId(product.getCategoryId());
productListVo.setSubtitle(product.getSubtitle());
productListVo.setPrice(product.getPrice());
productListVo.setMainImage(product.getMainImage());
productListVo.setStatus(product.getStatus());
productListVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix","http://image.mmall.com/"));
return productListVo;
}
- sql
<select id="selectByNameAndProductId" resultMap="BaseResultMap">
select <include refid="Base_Column_List"></include>
from mmall_product
<where>
<if test="productName != null">
and name like #{productName}
</if>
<if test="productId != null">
and id like #{productId}
</if>
</where>
</select>
六、Mybatis語句
- Mybatis-Mapper
public interface ProductMapper {
int deleteByPrimaryKey(Integer id);
int insert(Product record);
int insertSelective(Product record);
Product selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Product record);
int updateByPrimaryKey(Product record);
//商品上下架
int updateBySaleStatus(@Param("productId") Integer productId, @Param("status") Integer status);
//商品列表
List<Product> selectList();
//商品搜索
List<Product> selectByNameAndProductId(@Param("productName") String productName,@Param("productId") Integer productId);
//前臺商品詳情
Product selectByProductId(@Param("productId") Integer productId);
List<Product> selectByNameAndCategoryIds(@Param("productName") String productName,@Param("categoryIdList")List<Integer> categoryIdList);
}
- Mybatis-SQL
<?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.mmall.dao.ProductMapper" >
<resultMap id="BaseResultMap" type="com.mmall.pojo.Product" >
<constructor >
<idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="category_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="name" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="subtitle" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="main_image" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="sub_images" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="detail" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="price" jdbcType="DECIMAL" javaType="java.math.BigDecimal" />
<arg column="stock" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="status" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="create_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
<arg column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
</constructor>
</resultMap>
<sql id="Base_Column_List" >
id, category_id, name, subtitle, main_image, sub_images, detail, price, stock, status,
create_time, update_time
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from mmall_product
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from mmall_product
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.mmall.pojo.Product" >
insert into mmall_product (id, category_id, name,
subtitle, main_image, sub_images,
detail, price, stock,
status, create_time, update_time
)
values (#{id,jdbcType=INTEGER}, #{categoryId,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{subtitle,jdbcType=VARCHAR}, #{mainImage,jdbcType=VARCHAR}, #{subImages,jdbcType=VARCHAR},
#{detail,jdbcType=VARCHAR}, #{price,jdbcType=DECIMAL}, #{stock,jdbcType=INTEGER},
#{status,jdbcType=INTEGER},now(), now()
)
</insert>
<insert id="insertSelective" parameterType="com.mmall.pojo.Product" >
insert into mmall_product
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="categoryId != null" >
category_id,
</if>
<if test="name != null" >
name,
</if>
<if test="subtitle != null" >
subtitle,
</if>
<if test="mainImage != null" >
main_image,
</if>
<if test="subImages != null" >
sub_images,
</if>
<if test="detail != null" >
detail,
</if>
<if test="price != null" >
price,
</if>
<if test="stock != null" >
stock,
</if>
<if test="status != null" >
status,
</if>
<if test="createTime != null" >
create_time,
</if>
<if test="updateTime != null" >
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="categoryId != null" >
#{categoryId,jdbcType=INTEGER},
</if>
<if test="name != null" >
#{name,jdbcType=VARCHAR},
</if>
<if test="subtitle != null" >
#{subtitle,jdbcType=VARCHAR},
</if>
<if test="mainImage != null" >
#{mainImage,jdbcType=VARCHAR},
</if>
<if test="subImages != null" >
#{subImages,jdbcType=VARCHAR},
</if>
<if test="detail != null" >
#{detail,jdbcType=VARCHAR},
</if>
<if test="price != null" >
#{price,jdbcType=DECIMAL},
</if>
<if test="stock != null" >
#{stock,jdbcType=INTEGER},
</if>
<if test="status != null" >
#{status,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
now(),
</if>
<if test="updateTime != null" >
now(),
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.mmall.pojo.Product" >
update mmall_product
<set >
<if test="categoryId != null" >
category_id = #{categoryId,jdbcType=INTEGER},
</if>
<if test="name != null" >
name = #{name,jdbcType=VARCHAR},
</if>
<if test="subtitle != null" >
subtitle = #{subtitle,jdbcType=VARCHAR},
</if>
<if test="mainImage != null" >
main_image = #{mainImage,jdbcType=VARCHAR},
</if>
<if test="subImages != null" >
sub_images = #{subImages,jdbcType=VARCHAR},
</if>
<if test="detail != null" >
detail = #{detail,jdbcType=VARCHAR},
</if>
<if test="price != null" >
price = #{price,jdbcType=DECIMAL},
</if>
<if test="stock != null" >
stock = #{stock,jdbcType=INTEGER},
</if>
<if test="status != null" >
status = #{status,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null" >
update_time = now(),
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.mmall.pojo.Product" >
update mmall_product
set category_id = #{categoryId,jdbcType=INTEGER},
name = #{name,jdbcType=VARCHAR},
subtitle = #{subtitle,jdbcType=VARCHAR},
main_image = #{mainImage,jdbcType=VARCHAR},
sub_images = #{subImages,jdbcType=VARCHAR},
detail = #{detail,jdbcType=VARCHAR},
price = #{price,jdbcType=DECIMAL},
stock = #{stock,jdbcType=INTEGER},
status = #{status,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time =now()
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateBySaleStatus" parameterType="map">
update mmall_product
set status=#{status}
where id=#{productId}
</update>
<select id="selectList" resultMap="BaseResultMap" >
select <include refid="Base_Column_List"></include>
from mmall_product
order by id asc
</select>
<select id="selectByNameAndProductId" resultMap="BaseResultMap">
select <include refid="Base_Column_List"></include>
from mmall_product
<where>
<if test="productName != null">
and name like #{productName}
</if>
<if test="productId != null">
and id like #{productId}
</if>
</where>
</select>
<select id="selectByProductId" resultMap="BaseResultMap" parameterType="int">
select <include refid="Base_Column_List"></include>
from mmall_product
where id=#{productId} and status=1
</select>
<select id="selectByNameAndCategoryIds" resultMap="BaseResultMap" parameterType="map">
select <include refid="Base_Column_List"></include>
from mmall_product
where status=1
<if test="productName != null">
and name like #{productName}
</if>
<if test="categoryIdList != null">
and category_id in
<foreach item="item" index="index" open="(" separator="," close=")" collection="categoryIdList">
#{item}
</foreach>
</if>
</select>
</mapper>