CGB2105-Day15

1. 全局异常处理/事务控制关系

在这里插入图片描述

2 商品分类业务实现

2.1 商品分类查询优化

2.1.1 现有代码存在的问题

问题说明: 如果经过2次for循环, 链接数据库的次数将会很多, 直接影响查询的效率.
优化: 尽可能的降低查询的次数,同时满足用户需求
在这里插入图片描述

2.1.2 优化策略

数据结构: Map<K,V> map
Key=“父级ID” Value=List<当前父级的子级>
用法: 如果想要获取任意父级的子级 map.get(父级的ID)
用法说明: Value 只有父级的子级信息,没有嵌套结构
Map<父级ID,List<ItemCat{id=xx,name=xx,children=null}>>

2.1.3 封装Map集合

原理图:
在这里插入图片描述

2.1.3 封装Map实现

  /**
     * 1.封装Map集合   Map<Key=父级ID,value=List<ItemCat对象>>
     * 2.说明:  将所有的数据库的父子关系,进行封装.(没有嵌套!!!!)
     * 3.优势:  只查询一次数据库,就可以完成父子关系的封装.
        策略:
     *      1. key不存在, 准备一个新List集合,将自己当作第一个元素追加
     *      2. key存在,  获取原有list集合,将自己追加.
     *
     */
    public Map<Integer,List<ItemCat>> initMap(){
        //Map中包含了所有的父子级关系.
        Map<Integer,List<ItemCat>> map = new HashMap<>();
        //1.查询item_cat表中的所有的记录(1/2/3级菜单)
        List<ItemCat> itemCatList = itemCatMapper.selectList(null);
        //2.实现数据的封装
        for(ItemCat itemCat : itemCatList){
            int key = itemCat.getParentId();
            if(map.containsKey(key)){ //存在
                List<ItemCat> list = map.get(key);
                //将自己追加到其中
                list.add(itemCat);
            }else{  //不存在: 准备List集合,将自己作为第一个元素封装
                List<ItemCat> list = new ArrayList<>();
                list.add(itemCat);
                map.put(key,list);
            }
        }
        //将封装的数据进行返回.
        return map;
    }

2.1.4 后台代码完整实现

 /**
     * 1.封装Map集合   Map<Key=父级ID,value=List<ItemCat对象>>
     * 2.说明:  将所有的数据库的父子关系,进行封装.(没有嵌套!!!!)
     * 3.优势:  只查询一次数据库,就可以完成父子关系的封装.
        策略:
     *      1. key不存在, 准备一个新List集合,将自己当作第一个元素追加
     *      2. key存在,  获取原有list集合,将自己追加.
     *
     */
    public Map<Integer,List<ItemCat>> initMap(){
        //Map中包含了所有的父子级关系.
        Map<Integer,List<ItemCat>> map = new HashMap<>();
        //1.查询item_cat表中的所有的记录(1/2/3级菜单)
        List<ItemCat> itemCatList = itemCatMapper.selectList(null);
        //2.实现数据的封装
        for(ItemCat itemCat : itemCatList){
            int key = itemCat.getParentId();
            if(map.containsKey(key)){ //存在
                List<ItemCat> list = map.get(key);
                //将自己追加到其中
                list.add(itemCat);
            }else{  //不存在: 准备List集合,将自己作为第一个元素封装
                List<ItemCat> list = new ArrayList<>();
                list.add(itemCat);
                map.put(key,list);
            }
        }
        //将封装的数据进行返回.
        return map;
    }


    /**
     * level 1 只查询一级商品分类
     *       2 查询一级/二级  嵌套封装
     *       3 查询一级/二级/三级   嵌套封装
     * @param level
     * @return
     */
    @Override
    public List<ItemCat> findItemCatList(Integer level) {
        long startTime = System.currentTimeMillis();
        //Map集合里边封装的是所有的父子级关系.
        Map<Integer,List<ItemCat>> map = initMap();
        if(level == 1){ //只获取1级菜单. parent_id = 0
            return map.get(0);
        }
        //用户查询1/2级商品分类信息
        if(level == 2){
            return getLevel2List(map);
        }

        //如果程序执行到这里,则说明用户查询的是1-2-3级菜单
        List<ItemCat> list = getLevel3List(map);
        long endTime = System.currentTimeMillis();
        System.out.println("耗时:"+(endTime-startTime)+"毫秒");
        return list;
    }

    public List<ItemCat> getLevel3List(Map<Integer, List<ItemCat>> map) {
        //1.先查询1-2级
        List<ItemCat> oneList = getLevel2List(map);

        //2.遍历集合
        for(ItemCat oneItemCat : oneList){
            //获取二级集合信息
            List<ItemCat> twoList = oneItemCat.getChildren();
            if(twoList == null || twoList.size() ==0){
                //当前一级菜单没有二级元素.结束本次循环,开始下一次!!!
                continue;
            }
            //该元素有二级,应该查询三级.
            for(ItemCat twoItemCat : twoList){
                List<ItemCat> threeList = map.get(twoItemCat.getId());
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }

    //查询一级和二级信息
    public List<ItemCat> getLevel2List(Map<Integer, List<ItemCat>> map) {
        //思路: 先查询一级,之后循环遍历,再次封装2级
        //1.获取一级
        List<ItemCat> oneList = map.get(0);
        for(ItemCat oneItemCat : oneList){
            //2.如何根据一级查询二级? 通过Map集合获取
            List<ItemCat> twoList = map.get(oneItemCat.getId());
            //3.实现了一级二级的封装
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }

2.2 商品分类状态修改

2.2.1 页面JS分析

在这里插入图片描述

2.2.2 业务接口文档说明

  • 请求路径: /itemCat/status/{id}/{status}
  • 请求类型: put
  • 请求参数:
参数名称参数说明备注
id用户ID值不能为null
status用户的状态信息不能为null
  • 返回值: SysResult对象
参数名称参数说明备注
status状态信息200表示服务器请求成功 201表示服务器异常
msg服务器返回的提示信息可以为null
data服务器返回的业务数据可以为null

2.2.3 编辑ItemCatController

 /**
     * 业务需求: 实现状态的修改
     * 1.URL: /itemCat/status/{id}/{status}
     * 2.请求类型: put
     * 3.返回值: SysResult对象
     */
    @PutMapping("/status/{id}/{status}")
    public SysResult updateStatus(ItemCat itemCat){

        itemCatService.updateStatus(itemCat);
        return SysResult.success();
    }

2.2.4 编辑ItemCatService

 @Override
    public void updateStatus(ItemCat itemCat) {//id/status

        itemCatMapper.updateById(itemCat);
    }

2.3 商品分类新增操作

2.3.1 业务说明

  1. 如果是一级菜单,则不需要勾选父级.
  2. 如果有父级,只能勾选1-2级.
    在这里插入图片描述

2.3.2 页面JS说明

  1. 商品分类菜单信息 2级展现JS
async findParentItemCatList() {
        //动态获取商品分类信息  type=2表示获取2级商品分类信息
        const {
          data: result
        } = await this.$http.get("/itemCat/findItemCatList/2")
        if (result.status !== 200) return this.$message.error("获取商品分类列表失败!!")
        this.parentItemCatList = result.data
      },
	
	//2.发起Ajax请求,实现新增操作
	 async addItemCatForm() {
        //先将整个表单进行校验
        this.$refs.itemCatFormRef.validate(async validate => {
          if (!validate) return
          const {
            data: result
          } = await this.$http.post("/itemCat/saveItemCat", this.itemCatForm)
          if (result.status !== 200) return this.$message.error("新增商品分类失败")
          this.$message.success("新增商品分类成功!!!")
          //新增成功,则刷新分类列表信息
          this.findItemCatList();
          this.addItemCatDialogVisible = false
        })
      },

2.3.3 业务接口文档说明

  • 请求路径: /itemCat/saveItemCat
  • 请求类型: post
  • 请求参数: 表单数据
参数名称参数说明备注
name商品分类名称不能为null
parentId用户父级ID不能为null
level分类级别1 2 3 商品分类级别
  • 返回值: SysResult对象
参数名称参数说明备注
status状态信息200表示服务器请求成功 201表示服务器异常
msg服务器返回的提示信息可以为null
data服务器返回的业务数据可以为null

2.3.4 编辑ItemCatController

 /**
     * 需求: 实现商品分类入库
     * URL: /itemCat/saveItemCat
     * 类型: post类型
     * 参数: itemCat对象~~~JSON
     * 返回值: SysResult
     */
    @PostMapping("/saveItemCat")
    public SysResult saveItemCat(@RequestBody ItemCat itemCat){

        itemCatService.saveItemCat(itemCat);
        return SysResult.success();
    }

2.3.5 编辑ItemCatServiceImpl

	@Override
    @Transactional
    public void saveItemCat(ItemCat itemCat) {

        itemCat.setStatus(true);
        itemCatMapper.insert(itemCat);
    }

2.4 商品分类删除操作

2.4.1 业务说明

1.如果被删除的标签是3级标签,则可以直接删除.
2.如果被删除的标签是2级标签,则需要先删除3级,再删除2级.
3.如果被删除的标签是1级标签,则需要先删除3级,在删除2级.最后删除1级.

2.4.2 页面JS分析

在这里插入图片描述

2.4.3 业务接口文档说明

  • 请求路径: /itemCat/deleteItemCat
  • 请求类型: delete
  • 业务描述: 当删除节点为父级时,应该删除自身和所有的子节点
  • 请求参数:
参数名称参数说明备注
id用户id号不能为null
level商品分类级别 一级,二级,三级
  • 返回值结果 SysResult对象
参数名称参数说明备注
status状态信息200表示服务器请求成功 201表示服务器异常
msg服务器返回的提示信息可以为null
data服务器返回的业务数据可以为null

2.4.4 编辑ItemCatController

 /**
     * 商品分类删除操作
     * URL:  /itemCat/deleteItemCat?id=1&level=3
     * 类型:  delete
     * 参数:  id/level
     * 返回值: SysResult对象
     */
    @DeleteMapping("/deleteItemCat")
    public SysResult deleteItemCat(Integer id,Integer level){

        itemCatService.deleteItemCat(id,level);
        return SysResult.success();
    }

2.4.5 编辑ItemCatServiceImpl

/**
     * 1.易用性,性能高
     *
     * @param id
     * @param level
     */
    @Override
    @Transactional  //添加事务的控制
    public void deleteItemCat(Integer id, Integer level) {
        if(level == 3){
            itemCatMapper.deleteById(id);
        }

        if(level == 2){
            //1.先删除3级菜单
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("parent_id",id);
            itemCatMapper.delete(queryWrapper);
            //2.再删除2级菜单
            itemCatMapper.deleteById(id);
        }

        //如果程序执行到这一行 则需要先删除3级/再删除2级/最后删除1级
        if(level == 1){
            List<Integer> ids = new ArrayList<>();
            //1.查询所有的二级菜单
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("parent_id",id);
            List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
            for (ItemCat twoItemCat : twoList){
                //删除3级菜单
                queryWrapper.clear();
                queryWrapper.eq("parent_id",twoItemCat.getId());
                //delete from item_cat where parent_id = "二级ID"
                itemCatMapper.delete(queryWrapper);
                //获取需要删除的ID信息
                ids.add(twoItemCat.getId());
            }
            //将所有的二级/一级ID封装到List集合中
            ids.add(id);
            itemCatMapper.deleteBatchIds(ids);
        }
    }

3. 商品管理实现

3.1 表设计

1.item表设计 商品表(商品的基本信息)
在这里插入图片描述
2.item_desc 表设计 商品详情表 item_desc 专门保存大字段(html/url/图片网址…)
在这里插入图片描述
设计要求: item表与itemDesc表应该一对一. item.id = itemDesc.id

3.2.Item POJO对象设计

/**
 * @author 刘昱江
 * 时间 2021/4/7
 */
@TableName("item")
@Data
@Accessors(chain = true)
public class Item extends BasePojo{
    @TableId(type = IdType.AUTO)
    private Integer id;         //商品Id号
    private String title;       //商品标题信息
    private String sellPoint;   //卖点信息
    private Integer price;      //商品价格 精度问题!!! 将小数扩大100倍 页面中将数据缩小100倍
    private Integer num;        //商品数量
    private String images;       //商品图片 1.jpg,2.jpg,3.jpg
    private Integer itemCatId;  //商品分类ID号
    private Boolean status;     //状态信息    0 下架 1 上架

}

3.3 商品列表展现

3.3.1 需求说明

要求: 当用户打开商品列表页面时,应该采用分页的方式 展现商品信息.
在这里插入图片描述

3.3.2 页面JS分析

在这里插入图片描述

3.3.3 业务接口文档实现

  • 请求路径: /item/getItemList?query=&pageNum=1&pageSize=10
  • 请求类型: get
  • 请求参数: 使用pageResult对象接收
参数名称参数说明备注信息
query用户查询的数据可以为null
pageNum分页查询的页数必须赋值不能为null
pageSize分页查询的条数必须赋值不能为null
  • 返回值结果:
参数名称参数说明备注
status状态信息200表示服务器请求成功 201表示服务器异常
msg服务器返回的提示信息可以为null
data服务器返回的业务数据商品分页对象

3.3.4 编辑ItemController

@RestController
@CrossOrigin
@RequestMapping("/item")
public class ItemController {

    @Autowired
    private ItemService itemService;

    /**
     * 业务逻辑: 查询商品分页
     * URL: /item/getItemList?query=&pageNum=1&pageSize=10
     * 类型: GET
     * 接收参数: PageResult对象
     * 返回值: SysResult
     */
    @GetMapping("/getItemList")
    public SysResult getItemList(PageResult pageResult){//3个参数

        //返回5个参数,total/rows分页记录
        pageResult = itemService.getItemList(pageResult);
        return SysResult.success(pageResult);
    }

}

3.3.5 编辑ItemServiceImpl

@Service
public class ItemServiceImpl implements ItemService{

    @Autowired
    private ItemMapper itemMapper;

    /**
     * 实现商品的分页操作
     * @param pageResult
     * @return
     */
    @Override
    public PageResult getItemList(PageResult pageResult) {
        //参数1:页数  参数2: 条数
        Page<Item> page = new Page<>(pageResult.getPageNum(),pageResult.getPageSize());
        QueryWrapper queryWrapper = new QueryWrapper();
        //如果参数有值true 如果query参数没有值 false
        boolean flag = StringUtils.hasLength(pageResult.getQuery());
        queryWrapper.like(flag,"title",pageResult.getQuery());
        //利用MP的分页API 实现查询
        page = itemMapper.selectPage(page,queryWrapper);
        long total = page.getTotal();
        List<Item> list = page.getRecords();
        //封装成功之后原来3个参数   封装之后变为5个 之后返回
        return pageResult.setTotal(total).setRows(list);
    }
}

3.3.6 页面效果展现

在这里插入图片描述

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

闪耀太阳

感觉文章不错的记得打赏呀

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

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

打赏作者

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

抵扣说明:

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

余额充值