3、显示全部商品
3.1、编写业务层代码
ProductInfoService
public interface ProductInfoService { //显示全部商品不分页 List<ProductInfo> getAllProduct(); }
3.2、编写控制层代码
ProductInfoServiceImpl
@Controller @RequestMapping("/prod") public class ProductInfoAction { @Autowired ProductInfoService productInfoService; //显示全部商品不分页 @RequestMapping("/getAll") private String getAllProduct(HttpServletRequest request){ List<ProductInfo> list = productInfoService.getAllProduct(); request.setAttribute("list", list); return "product"; } }
3.3、商品管理页
4、分页显示商品
4.1、编写业务层代码
ProductInfoService
public interface ProductInfoService { //显示全部商品不分页 List<ProductInfo> getAllProduct(); //商品分页显示 //使用mybits提供的插件,返回值是PageInfo,形参传入(当前页,每页显示条数) PageInfo splitPage(int pageNum, int pageSize); }
ProductInfoServiceImpl
@Service public class ProductInfoServiceImpl implements ProductInfoService { @Autowired ProductInfoMapper productInfoMapper; @Override public List<ProductInfo> getAllProduct() { return productInfoMapper.selectByExample(new ProductInfoExample()); } @Override public PageInfo splitPage(int pageNum, int pageSize) { //分页插件pageHelper工具类完成分页设置 //SELECT * FROM product_info LIMIT 10,5; PageHelper.startPage(pageNum, pageSize); //进行PageInfo的数据封装,然后返回一个pageinfo对象就行了 //1、进行条件查询,必须创建ProductInfoExample对象 ProductInfoExample example = new ProductInfoExample(); //2、设置排序,按主键降序排序 //SELECT * FROM product_info ORDER BY p_id DESC; example.setOrderByClause("p_id desc"); //3、排完序后,取集合。切记:一定在取集合前,设置PageHelper.startPage(pageNum, pageSize); List<ProductInfo> list = productInfoMapper.selectByExample(example); //4、将倒序排的集合,封装为PageInfo PageInfo<ProductInfo> pageInfo = new PageInfo<>(list); return pageInfo; } }
4.2、编写控制层代码
@Controller @RequestMapping("/prod") public class ProductInfoAction { //每页显示的记录数 public static final int PAGE_SIZE = 5; @Autowired ProductInfoService productInfoService; //显示全部商品不分页 @RequestMapping("/getAll") private String getAllProduct(HttpServletRequest request) { List<ProductInfo> list = productInfoService.getAllProduct(); request.setAttribute("list", list); return "product"; } //显示第一页的5条记录 @RequestMapping("/split") private String split(HttpServletRequest request) { //得到第一页的数据 PageInfo info = productInfoService.splitPage(1, PAGE_SIZE); request.setAttribute("info", info); return "product"; } //Ajax分页的翻页处理 @ResponseBody @RequestMapping("/ajaxSplit") private void ajaxSplit(int page, HttpSession session) { //取得当前page参数的页面数据 PageInfo info = productInfoService.splitPage(page, PAGE_SIZE); session.setAttribute("info", info); } }
4.3、商品分页显示
5、新增(上架)商品
5.1、获取商品类别
ProductTypeListener
package com.jerry.listener; import com.jerry.pojo.ProductType; import com.jerry.service.ProductTypeService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import java.util.List; /** * ClassName: ProductTypeListener * Package: com.jerry.listener * Description: * * @Author jerry_jy * @Create 2023-02-13 16:47 * @Version 1.0 */ @WebListener public class ProductTypeListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { //Spring注册监听器也是通过ContextLoaderListener,因此我们要手动管理ProductTypeListener //如果交给Spring管理就不知道哪个Listener先被创建 //1、手动从Spring容器中取出ProductTypeServiceImpl的对象 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext_*.xml"); ProductTypeService productTypeService = (ProductTypeService) context.getBean("ProductTypeServiceImpl"); List<ProductType> typeList = productTypeService.getAll(); //2、放入全局作用域中,供新增页面、修改页面、前台的查询功能提供全部的商品类别集合 servletContextEvent.getServletContext().setAttribute("typeList",typeList); } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { } }
5.2、Ajax上传图片并回显
ProductInfoAction
//异步Ajax文件上传处理 @ResponseBody @RequestMapping("ajaxImg") public Object ajaxImg(MultipartFile pimage,HttpServletRequest request){ //1、提取、生成文件名UUID+上传图片后缀名.jpg .png String saveFileName = FileNameUtil.getUUIDFileName() + FileNameUtil.getFileType(pimage.getOriginalFilename()); //2、获取图片的存取路径 String path = request.getServletContext().getRealPath("/image_big"); //3、转存 try { pimage.transferTo(new File(path+File.separator+saveFileName)); } catch (IOException e) { throw new RuntimeException(e); } //返回客户端的JSON对象, 封装图片路径,为了在页面上回显图片 JSONObject object = new JSONObject(); object.put("imgurl", saveFileName); return object.toString(); }
5.3、新增商品
业务层
ProductInfoService
//新增商品 int save(ProductInfo info);
ProductInfoServiceImpl
@Override public int save(ProductInfo info) { return productInfoMapper.insert(info); }
控制层
ProductInfoAction
//新增商品 @RequestMapping("/save") public String save(ProductInfo info, HttpServletRequest request) { info.setpImage(saveFileName); info.setpDate(new Date()); int num=-1; try { num=productInfoService.save(info); } catch (Exception e) { throw new RuntimeException(e); } if (num>0){ request.setAttribute("msg", "增加成功"); }else { request.setAttribute("msg", "增加失败"); } //增加成功后应该重新访问数据库,所以跳转到分页显示的action上 return "forward:/prod/split.action"; }
5.4、新增(上架)商品页面展示
6、更新商品
6.1、回显并更新商品
业务层
ProductInfoService
//按主键id查询商品 ProductInfo selectById(int pid); //更新商品 int update(ProductInfo info);
ProductInfoServiceImpl
@Override public ProductInfo selectById(int pid) { return productInfoMapper.selectByPrimaryKey(pid); } @Override public int update(ProductInfo info) { return productInfoMapper.updateByPrimaryKey(info); }
控制层
ProductInfoAction
//根据主键id查询商品 @RequestMapping("/one") public String one(int pid, Model model){ ProductInfo info = productInfoService.selectById(pid); model.addAttribute("prod", info); return "update"; } //更新商品 @RequestMapping("/update") public String update(ProductInfo info, HttpServletRequest request) { //1、因为Ajax的异步图片上传,如果有上传过,则 saveFileName 里有上传过来的名称, //如果没有使用异步Ajax上传过图片,则saveFileName="",则实体类使用隐藏表单域提供上来的pImage原始图片的名称; if (!saveFileName.equals("")) { info.setpImage(saveFileName); } //完成更新处理 int num = -1; //切记:对于增删改的操作,一定要进行try-catch的异常捕获 try { num = productInfoService.update(info); } catch (Exception e) { throw new RuntimeException(e); } if (num>0){ //更新成功 request.setAttribute("msg", "更新成功"); }else { //更新失败 request.setAttribute("msg", "更新失败"); } //处理完更新后,saveFileName里可能有数据 //而下一次使用这个变量作为判断的依据,就会出错,所以必须清空saveFileName saveFileName = ""; //redirect会导致request请求丢失,改用forward return "forward:/prod/split.action"; }
6.2、页面展示
7、删除商品
7.1、单个删除
ProductInfoService
//单个商品的删除 int delete(int pid);
ProductInfoServiceImpl
@Override public int delete(int pid) { return productInfoMapper.deleteByPrimaryKey(pid); }
ProductInfoAction
//单个删除 @RequestMapping("/delete") public String delete(int pid, HttpServletRequest request) { int num = -1; try { num = productInfoService.delete(pid); } catch (Exception e) { throw new RuntimeException(e); } if (num > 0) { request.setAttribute("msg", "删除成功"); } else { request.setAttribute("msg", "删除失败"); } return "forward:/prod/deleteAjaxSplit.action"; } @ResponseBody @RequestMapping(value = "deleteAjaxSplit", produces = "text/html;charset=UTF-8") public Object deleteAjaxSplit(HttpServletRequest request) { //取第一页的数据 PageInfo info = productInfoService.splitPage(1, PAGE_SIZE); request.getSession().setAttribute("info", info); return request.getAttribute("msg"); }
7.2、批量删除
ProductInfoMapper
//批量删除商品的功能 int deleteBatch(String []ids);
ProductInfoMapper.xml
<delete id="deleteBatch"> delete from product_info where p_id in <foreach collection="array" item="pid" separator="," open="(" close=")"> #{pid} </foreach> </delete>
ProductInfoService
//批量删除商品 int deleteBatch(String []ids);
ProductInfoServiceImpl
@Override public int deleteBatch(String[] ids) { return productInfoMapper.deleteBatch(ids); }
ProductInfoAction
//批量删除商品 @RequestMapping("/deleteBatch") public String deleteBatch(String pids, HttpServletRequest request) { //将上传上来的字符串截断开,形成商品id的字符数组 String[] split = pids.split(","); int num = -1; try { num = productInfoService.deleteBatch(split); } catch (Exception e) { throw new RuntimeException(e); } try { if (num > 0){ request.setAttribute("msg", "批量删除成功"); }else { request.setAttribute("msg", "批量删除失败"); } } catch (Exception e) { request.setAttribute("msg", "商品不能删除"); } return "forward:/prod/deleteAjaxSplit.action"; }
7.3、页面展示
单个删除
批量删除
8、查询商品
8.0、编写多条件查询语句
多条件的查询【条件】封装在vo对象中
package com.jerry.pojo.vo; /** * ClassName: ProductInfoVo * Package: com.jerry.pojo.vo * Description: * * @Author jerry_jy * @Create 2023-02-14 11:49 * @Version 1.0 */ public class ProductInfoVo { //商品名称 private String pname; //商品类型 private Integer typeid; //最低价格 private Integer lprice; //最高价格 private Integer hprice; //设置页码 private Integer page = 1; public ProductInfoVo() { } public ProductInfoVo(String pname, Integer typeid, Integer lprice, Integer hprice, Integer page) { this.pname = pname; this.typeid = typeid; this.lprice = lprice; this.hprice = hprice; this.page = page; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public Integer getTypeid() { return typeid; } public void setTypeid(Integer typeid) { this.typeid = typeid; } public Integer getLprice() { return lprice; } public void setLprice(Integer lprice) { this.lprice = lprice; } public Integer getHprice() { return hprice; } public void setHprice(Integer hprice) { this.hprice = hprice; } public Integer getPage() { return page; } public void setPage(Integer page) { this.page = page; } @Override public String toString() { return "ProductInfoVo{" + "pname='" + pname + '\'' + ", typeid=" + typeid + ", lprice=" + lprice + ", hprice=" + hprice + ", page=" + page + '}'; } }
ProductInfoMapper
//多条件查询 List<ProductInfo> selectCondition(ProductInfoVo vo);
ProductInfoMapper.xml
<!-- 多条件查询 拼接 List<ProductInfo> selectCondition(ProductInfoVo vo); --> <select id="selectCondition" parameterType="com.jerry.pojo.vo.ProductInfoVo" resultMap="BaseResultMap"> select <include refid="Base_Column_List"></include> from product_info <!--拼接条件--> <where> <!--商品名称不为空,拼接商品名称模糊查询--> <if test="pname != null and pname != -1"> and p_name like '%${pname}%' </if> <!--商品类型不为空,拼接商品类型查询--> <if test="typeid != null and type != ''"> and type_id = #{typeid} </if> <!--如果最低价格不为空 且大于0(vo在类中实现),最高价格为空,则查询大于最低价格的所有商品--> <if test="(lprice != null and lprice != '') and (hprice == null or hprice == '')"> and p_price >= #{lprice} </if> <!--如果最低价格为空,最高价格不为空 且大于0,则查询小于最高价格的所有商品--> <if test="(lprice == null or lprice == '') and (hprice != null and hprice != '')"> and p_price <= #{hprice} </if> <!--如果最低价格不为空,最高价格不为空,则查询介于最高价格和最低价格之间的所有商品--> <if test="(lprice != null and lprice != '') and (hprice != null and hprice != '')"> and p_price between #{lprice} and #{hprice} </if> </where> order by p_id desc </select>
SelectConditionTest
package com.jerry; import com.jerry.mapper.ProductInfoMapper; import com.jerry.pojo.ProductInfo; import com.jerry.pojo.vo.ProductInfoVo; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.List; /** * ClassName: SelectConditionTest * Package: com.jerry * Description: * * @Author jerry_jy * @Create 2023-02-14 12:24 * @Version 1.0 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext_dao.xml","classpath:applicationContext_service.xml"}) public class SelectConditionTest { @Autowired ProductInfoMapper productInfoMapper; @Test public void test(){ ProductInfoVo vo = new ProductInfoVo(); List<ProductInfo> list = productInfoMapper.selectCondition(vo); list.forEach(System.out::println); } }
8.1、编写业务层代码
ProductInfoService
//多条件商品的查询 分页 PageInfo<ProductInfo> splitPageVo(ProductInfoVo vo, int pageSize);
ProductInfoServiceImpl
@Override public PageInfo<ProductInfo> splitPageVo(ProductInfoVo vo, int pageSize) { //取出集合之前,先要取出PageHelper.startPage()属性设置 PageHelper.startPage(vo.getPage(), pageSize); List<ProductInfo> list = productInfoMapper.selectCondition(vo); return new PageInfo<>(list); }
8.2、编写控制层代码
package com.jerry.controller; import com.github.pagehelper.PageInfo; import com.jerry.pojo.ProductInfo; import com.jerry.pojo.vo.ProductInfoVo; import com.jerry.service.ProductInfoService; import com.jerry.utils.FileNameUtil; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.List; /** * ClassName: ProductInfoAction * Package: com.jerry.controller * Description: * * @Author jerry_jy * @Create 2023-02-13 11:33 * @Version 1.0 */ @Controller @RequestMapping("/prod") public class ProductInfoAction { //每页显示的记录数 public static final int PAGE_SIZE = 5; //异步上传的文件图片的名称 String saveFileName = ""; @Autowired ProductInfoService productInfoService; //显示全部商品不分页 @RequestMapping("/getAll") public String getAllProduct(HttpServletRequest request) { List<ProductInfo> list = productInfoService.getAllProduct(); request.setAttribute("list", list); return "product"; } //显示第一页的5条记录 @RequestMapping("/split") public String split(HttpServletRequest request) { PageInfo info = null; Object vo = request.getSession().getAttribute("prodVo"); if (vo != null) { info = productInfoService.splitPageVo((ProductInfoVo) vo, PAGE_SIZE); request.getSession().removeAttribute("prodVo"); } else { //得到第一页的数据 info = productInfoService.splitPage(1, PAGE_SIZE); } request.setAttribute("info", info); return "product"; } //Ajax分页的翻页处理 @ResponseBody @RequestMapping("/ajaxSplit") public void ajaxSplit(ProductInfoVo vo, HttpSession session) { //取得当前page参数的页面数据 PageInfo info = productInfoService.splitPageVo(vo, PAGE_SIZE); session.setAttribute("info", info); } //异步Ajax文件上传处理 @ResponseBody @RequestMapping("ajaxImg") public Object ajaxImg(MultipartFile pimage, HttpServletRequest request) { //1、提取、生成文件名UUID+上传图片后缀名.jpg .png saveFileName = FileNameUtil.getUUIDFileName() + FileNameUtil.getFileType(pimage.getOriginalFilename()); //2、获取图片的存取路径 String path = request.getServletContext().getRealPath("/image_big"); //3、转存 try { pimage.transferTo(new File(path + File.separator + saveFileName)); } catch (IOException e) { throw new RuntimeException(e); } //返回客户端的JSON对象, 封装图片路径,为了在页面上回显图片 JSONObject object = new JSONObject(); object.put("imgurl", saveFileName); return object.toString(); } //新增商品 @RequestMapping("/save") public String save(ProductInfo info, HttpServletRequest request) { info.setpImage(saveFileName); info.setpDate(new Date()); int num = -1; try { num = productInfoService.save(info); } catch (Exception e) { throw new RuntimeException(e); } if (num > 0) { request.setAttribute("msg", "增加成功"); } else { request.setAttribute("msg", "增加失败"); } //清空saveFileName这个变量,为了下次新增或修改的异步Ajax的上传处理 saveFileName = ""; //增加成功后应该重新访问数据库,所以跳转到分页显示的action上 return "forward:/prod/split.action"; } //根据主键id查询商品 @RequestMapping("/one") public String one(int pid, ProductInfoVo vo, Model model, HttpSession session) { ProductInfo info = productInfoService.selectById(pid); model.addAttribute("prod", info); //将多条件以及页码放在session中,更新处理结束后,分页时读取条件和页码 session.setAttribute("prodVo", vo); return "update"; } //更新商品 @RequestMapping("/update") public String update(ProductInfo info, HttpServletRequest request) { //1、因为Ajax的异步图片上传,如果有上传过,则 saveFileName 里有上传过来的名称, //如果没有使用异步Ajax上传过图片,则saveFileName="",则实体类使用隐藏表单域提供上来的pImage原始图片的名称; if (!saveFileName.equals("")) { info.setpImage(saveFileName); } //完成更新处理 int num = -1; //切记:对于增删改的操作,一定要进行try-catch的异常捕获 try { num = productInfoService.update(info); } catch (Exception e) { throw new RuntimeException(e); } if (num > 0) { //更新成功 request.setAttribute("msg", "更新成功"); } else { //更新失败 request.setAttribute("msg", "更新失败"); } //处理完更新后,saveFileName里可能有数据 //而下一次使用这个变量作为判断的依据,就会出错,所以必须清空saveFileName saveFileName = ""; //redirect会导致request请求丢失,改用forward return "forward:/prod/split.action"; } //单个删除 @RequestMapping("/delete") public String delete(int pid, ProductInfoVo vo, HttpServletRequest request) { int num = -1; try { num = productInfoService.delete(pid); } catch (Exception e) { throw new RuntimeException(e); } if (num > 0) { request.setAttribute("msg", "删除成功"); request.getSession().setAttribute("deleteProductVo", vo); } else { request.setAttribute("msg", "删除失败"); } return "forward:/prod/deleteAjaxSplit.action"; } @ResponseBody @RequestMapping(value = "deleteAjaxSplit", produces = "text/html;charset=UTF-8") public Object deleteAjaxSplit(HttpServletRequest request) { //取第一页的数据 PageInfo info = null; Object vo = request.getSession().getAttribute("deleteProductVo"); if (vo != null) { info = productInfoService.splitPageVo((ProductInfoVo) vo, PAGE_SIZE); } else { info = productInfoService.splitPage(1, PAGE_SIZE); } request.getSession().setAttribute("info", info); return request.getAttribute("msg"); } //批量删除商品 @RequestMapping("/deleteBatch") public String deleteBatch(String pids, HttpServletRequest request) { //将上传上来的字符串截断开,形成商品id的字符数组 String[] split = pids.split(","); int num = -1; try { num = productInfoService.deleteBatch(split); } catch (Exception e) { throw new RuntimeException(e); } try { if (num > 0) { request.setAttribute("msg", "批量删除成功"); } else { request.setAttribute("msg", "批量删除失败"); } } catch (Exception e) { request.setAttribute("msg", "商品不能删除"); } return "forward:/prod/deleteAjaxSplit.action"; } //多条件商品的查询 @ResponseBody @RequestMapping("/condition") public void condition(ProductInfoVo vo, HttpSession session) { List<ProductInfo> list = productInfoService.selectCondition(vo); session.setAttribute("list", list); } }
8.3、页面展示
9、项目托管
Gitee
https://gitee.com/jinyang-jy/xiaomissm.git
GitHub
https://github.com/Jerry-jy/missm.git
10、项目所需前端页面资料
链接:https://pan.baidu.com/s/1CGnGV4anjBHVI_tLqLYXfw?pwd=2022
提取码:2022
–end–