完整项目学习-5

1. Mybaits-plus 项目整合

1.1 修改案例讲解

/**
     * MP更新操作
     * 说明: 将id=354 的名称改为"六耳猕猴"
     */
    @Test
    public void updateUserById(){
    
    
        User user = new User(354,"六耳猕猴",null,null);
        int rows = userMapper.updateById(user);
        System.out.println("响应了"+ rows +"行");
    }

    /**
     * MP更新操作
     * 说明: 将名称为"猴子"的数据改为"齐天大圣"
     * 用法:
     *      1. 参数1, 将修改的数据封装.
     *      2. 参数2, 将修改的条件封装
     * Sql: update demo_user set name="齐天大圣" where name="猴子"
     */
    @Test
    public void updateUserByName(){
    
    
        //1.利用pojo对象封装修改数据
        User user = new User(null,"齐天大圣",null,null);
        //1.利用UpdateWrapper封装where条件
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("name","猴子");
        userMapper.update(user,updateWrapper);
        System.out.println("修改操作成功!!!");
    }

1.2 MP后台项目改造

1.2.1 导入jar包

 		<!--导入MP的jar包文件-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>

1.2.2 编辑POJO ItemCat

@Data
@Accessors(chain = true)
@TableName("item_cat") //关联数据表
public class ItemCat extends BasePojo{
    
    

    @TableId(type = IdType.AUTO)//主键自增
    private Integer id;         //定义主键
    private Integer parentId;   //定义父级菜单 开启驼峰规则映射
    private String name;        //分类名称
    private Boolean status;     //分类状态 0 停用 1 正常
    private Integer level;      //商品分类等级  1 2 3
    @TableField(exist = false)  //属性不是表字段
    private List<ItemCat> children;
}

1.2.3 编辑ItemCatMapper接口

public interface ItemCatMapper extends BaseMapper<ItemCat> {
    
    

}

1.2.4 修改YML文件

#配置端口号
server:
  port: 8091

#管理数据源
spring:
  datasource:
    #高版本驱动使用
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    #设定用户名和密码
    username: root
    password: root

#SpringBoot整合Mybatis-plus
mybatis-plus:
  #指定别名包
  type-aliases-package: com.jt.pojo
  #扫描指定路径下的映射文件
  mapper-locations: classpath:/mybatis/mappers/*.xml
  #开启驼峰映射
  configuration:
    map-underscore-to-camel-case: true
  # 一二级缓存默认开始 所以可以简化

#打印mysql日志
logging:
  level:
    com.jt.mapper: debug

1.2.5 层级代码结构

在这里插入图片描述

1.3 商品分类页面跳转

说明: 编辑路由 index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import ElementUI from '../components/ElementUI.vue'
import Home from '../components/Home.vue'
import User from '../components/user/user.vue'
import ItemCat from '../components/items/ItemCat.vue'
//使用路由机制
Vue.use(VueRouter)
const routes = [
  {
    
    path: '/', redirect: '/login'},
  {
    
    path: '/login', component: Login},
  {
    
    path: '/elementUI', component: ElementUI},
  {
    
    path: '/home', component: Home, children: [
    {
    
    path: '/user', component: User},
     {
    
    path: '/itemCat', component: ItemCat}
  ]}
]

页面效果展现
在这里插入图片描述

2 完成商品分类业务

2.1 页面JS分析

  1. 生命周期函数
	//定义初始化函数
    created() {
    
    
      //默认获取商品分类列表数据
      this.findItemCatList()
    },
  1. 获取数据函数说明
async findItemCatList() {
    
    
        const {
    
    
          data: result
        } = await this.$http.get("/itemCat/findItemCatList/3")
        if (result.status !== 200) return this.$message.error("获取商品分类列表失败!!")
        this.itemCatList = result.data
      },

2.2 业务接口文档

  • 请求路径: /itemCat/findItemCatList/{level}
  • 请求类型: get
  • 请求参数: level
参数名称 参数说明 备注
level 查询级别 1查询一级分类 2查询1-2 级商品分类 3查询1-2-3级商品分类
  • 业务说明: 查询3级分类菜单数据 要求三层结构嵌套
  • 返回值: SysResult对象
参数名称 参数说明 备注
status 状态信息 200表示服务器请求成功
msg 服务器返回的提示信息 可以为null
data 服务器返回的业务数据 3级商品分类信息

2.3 商品分类表结构说明

  1. 表结构
    在这里插入图片描述
  2. sql案例练习
/*所有的一级菜单 parent_id=0*/
SELECT * FROM item_cat WHERE parent_id = 0
/*查询汽车用户的二级菜单*/
SELECT * FROM item_cat WHERE parent_id = 249
/*查询车载电器的三级菜单*/
SELECT * FROM item_cat WHERE parent_id = 281

小结: 商品分类表,通过parent_id 来指定父子级关系.

2.4 编辑ItemCatController

@RestController
@CrossOrigin
@RequestMapping("/itemCat")
public class ItemCatController {
    
    

    @Autowired
    private ItemCatService itemCatService;

    /**
     * 需求: 查询商品分类信息
     * 参数: /{level}   1一级  2 一二级  3 一二三级
     * url: /itemCat/findItemCatList/{level}  restFul
     * 返回值: SysResult(3级列表信息)
     */
    @GetMapping("findItemCatList/{level}")
    public SysResult findItemCatList(@PathVariable Integer level){
    
    

        List<ItemCat> itemCatList = itemCatService.findItemCatList(level);
        return SysResult.success(itemCatList);
    }

}

2.5 编辑ItemCatService

package com.jt.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.ItemCatMapper;
import com.jt.pojo.ItemCat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ItemCatServiceImpl implements ItemCatService{
    
    

    @Autowired
    private ItemCatMapper itemCatMapper;

    /**
     * 步骤1.查询一级菜单列表
     * @param level
     * @return
     */
    @Override
    public List<ItemCat> findItemCatList(Integer level) {
    
    
        //1.查询一级菜单
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("parent_id",0);
        List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);
        //2.查询二级菜单 二级数据是一级数据的子级 封装到一级数据中.
        for(ItemCat oneItemCat : oneList){
    
    
            int oneId = oneItemCat.getId(); //一级对象ID
            //清空原始条件  必须有
            queryWrapper.clear();
            queryWrapper.eq("parent_id",oneId);
            List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
            for(ItemCat twoItemCat : twoList){
    
    
                //获取二级分类ID
                int twoId = twoItemCat.getId();
                //查询三级列表信息
                queryWrapper.clear();
                queryWrapper.eq("parent_id",twoId);
                List<ItemCat> threeList = itemCatMapper.selectList(queryWrapper);
                //将三级列表 封装到二级对象中
                twoItemCat.setChildren(threeList);
            }
            //将二级数据封装到一级对象中
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }
}

2.6 上述案例分析

  1. 上述的案例 采用多级循环的方式. 将来会耗费服务器资源 100次 内层100次 总循环1万次. 暂时可以接受
  2. 上述的代码 频繁访问数据库.导致数据库压力增大.严重时可能导致数据库服务器宕机. 不能接受的
    优化策略: 降低数据库访问的次数

2.7 采用数据结构优化代码

思路:

  1. 用户查询所有的数据库信息. (1-2-3所有数据)
  2. 数据结构 Map<k,v> key唯一的, value可以任意类型.
    思路: Map<parentId,List>
    例子:
  3. Map<0,List<一级ItemCat对象>>
  4. Map<249,List<二级ItemCat对象>>
  5. Map<281,List<三级ItemCat对象>>
    利用map 封装父子关系.

2.8 代码具体实现

@Service
public class ItemCatServiceImpl implements ItemCatService{
    
    

    @Autowired
    private ItemCatMapper itemCatMapper;

    /**
     * 利用Map集合封装所有的数据库记录
     * 封装数据:
     *      1.遍历所有的数据信息.
     *      2.获取每一个parentId的值.
     * 例子:
     *      1.{id=1,parentId=0,name="张三"}
     *      2.{id=2,parentId=0,name="李四"}
     *      3.{id=3,parentId=1,name="王五"}
     *      Map= {
     *          key : value
     *          0   : List[张三对象,李四对象.....],
     *          1   : List[王五对象......]
     *      }
     * @return
     */
    public Map<Integer,List<ItemCat>> getMap(){
    
    
        Map<Integer,List<ItemCat>> map = new HashMap<>();
        //1.查询所有的数据库信息
        List<ItemCat> itemCatList = itemCatMapper.selectList(null);
        //2.将数据封装到map集合中
        for (ItemCat itemCat : itemCatList){
    
    
            Integer key = itemCat.getParentId(); //获取parentId当做key
            //3.判断map集合中是否有值.
            if(map.containsKey(key)){
    
    
                //有值: 获取List集合,将自己追加到其中
                map.get(key).add(itemCat);
            }else{
    
    
                //没值: 添加数据.将自己作为第一个元素填充
                List<ItemCat> list = new ArrayList<>();
                list.add(itemCat);
                map.put(key,list);
            }
        }
        return map;
    }

    @Override
    public List<ItemCat> findItemCatList(Integer level) {
    
    
        long startTime = System.currentTimeMillis();
        Map<Integer,List<ItemCat>> map = getMap();
        //根据level获取子级信息
        if(level == 1){
    
     //只获取一级列表信息
            return map.get(0);
        }
        if(level == 2){
    
     //获取一级和二级数据
            return getTwoList(map);
        }
        List<ItemCat> oneList = getThreeList(map);
        long endTime = System.currentTimeMillis();
        System.out.println("优化前的耗时: 500ms,优化后耗时:"+(endTime - startTime)+"ms");
        return oneList;
    }

    //获取三级列表信息  先获取1级数据,再获取2级数据.再获取3级数据

    private List<ItemCat> getThreeList(Map<Integer, List<ItemCat>> map) {
    
    
        //1.调用2级菜单方法.
        List<ItemCat> oneList = getTwoList(map);
        //2.实现思路 遍历一级集合,获取二级数据. 封装三级菜单
        for(ItemCat oneItemCat : oneList){
    
    
            //2.1 获取二级数据
            List<ItemCat> twoList = oneItemCat.getChildren();
            if(twoList == null || twoList.size()==0){
    
    
                //判断二级集合是否为null.如果为null,表示没有二级菜单.
                continue;
            }
            for (ItemCat twoItemCat : twoList){
    
    
                int twoId = twoItemCat.getId();
                List<ItemCat> threeList = map.get(twoId);
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }

    //通过map集合 获取一级二级菜单信息.
    private List<ItemCat> getTwoList(Map<Integer, List<ItemCat>> map) {
    
    
        List<ItemCat> oneList = map.get(0);
        //获取二级信息,应该先遍历一级集合
        for (ItemCat oneItemCat : oneList){
    
    
            int oneId = oneItemCat.getId();
            //根据一级Id,获取二级集合
            List<ItemCat> twoList = map.get(oneId);
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }


    /**
     * 步骤1.查询一级菜单列表
     * @param level
     * @return
     */
   /* @Override
    public List<ItemCat> findItemCatList(Integer level) {
        long startTime = System.currentTimeMillis();
        //1.查询一级菜单
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("parent_id",0);
        List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);
        //2.查询二级菜单 二级数据是一级数据的子级 封装到一级数据中.
        for(ItemCat oneItemCat : oneList){
            int oneId = oneItemCat.getId(); //一级对象ID
            //清空原始条件  必须有
            queryWrapper.clear();
            queryWrapper.eq("parent_id",oneId);
            List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
            for(ItemCat twoItemCat : twoList){
                //获取二级分类ID
                int twoId = twoItemCat.getId();
                //查询三级列表信息
                queryWrapper.clear();
                queryWrapper.eq("parent_id",twoId);
                List<ItemCat> threeList = itemCatMapper.selectList(queryWrapper);
                //将三级列表 封装到二级对象中
                twoItemCat.setChildren(threeList);
            }
            //将二级数据封装到一级对象中
            oneItemCat.setChildren(twoList);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("耗时:"+ (endTime - startTime)+"ms");
        return oneList;
    }*/
}

3 商品分类新增实现

3.1 页面JS分析

  1. 页面JS分析
 		//定义商品分类新增对象
        itemCatForm: {
    
    
          name: '', //定义商品分类名称
          parentId: 0, //默认父级ID=0
          level: 1 //默认是一级菜单
        },
		
		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
        })
      },

3.2 商品分类新增接口文档

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

3.3 编辑ItemCatController

/**
     * 业务需求:  实现商品分类新增
     * URL:  /itemCat/saveItemCat
     * 类型: post
     * 参数: {"name":"AAAAAA","parentId":0,"level":1} json串
     * 返回值: SysResult对象
     */
    @PostMapping("/saveItemCat")
    public SysResult saveItem(@RequestBody ItemCat itemCat){
    
    

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

3.4 编辑ItemCatService

	@Override
    @Transactional  //事务控制
    public void saveItem(ItemCat itemCat) {
    
    
        Date date = new Date();
        itemCat.setStatus(true).setCreated(date).setUpdated(date);//启动
        itemCatMapper.insert(itemCat);
    }

4. 商品分类删除操作

4.1 删除业务接口

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

4.2 前端页面JS

1. 页面JS
<el-button type="danger" icon="el-icon-delete" @click="deleteItemCatBtn(scope.row)">删除</el-button>


2. 发起Ajax请求
//传递分类id
        const {
    
    data: result} = await this.$http.delete("/itemCat/deleteItemCat",{
    
    params:{
    
    id:itemCat.id,level:itemCat.level}})
          if(result.status !== 200) return this.$message.error("删除商品分类失败")
          this.$message.success("删除数据成功")
          //删除成功之后,刷新页面数据
          this.findItemCatList()          

4.3 编辑ItemCatController

 /**
     * 完成商品分类的删除操作
     * 1. 编辑URL: /itemCat/deleteItemCat
     * 2. 参数: id/level
     * 3. 返回值: SysResult()
     */
    @DeleteMapping("/deleteItemCat")
    public SysResult deleteItemCat(Integer id,Integer level){
    
    

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

4.4 编辑ItemCatService

//删除商品分类数据
    @Override
    public void deleteItemCat(Integer id, Integer level) {
    
    
        //判断是否为3级菜单
        if(level == 3){
    
    
            itemCatMapper.deleteById(id);
        }

        if(level == 2){
    
    
            //如果是二级,应该先获取三级数据之后删除,再删除自己
            //delete from item_cat where parent_id=#{id} or id = #{id}
            QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id",id)
                        .or()
                        .eq("id",id);
            itemCatMapper.delete(queryWrapper);
        }

        /**
         * 如何删除一级菜单?
         *  1.获取二级ID
         *  终极sql: delete from item_cat where parent_id in (twoIds)
         *          or  id in (twoIds)
         *          or  id = #{id}
         */
        if(level == 1){
    
    
            QueryWrapper<ItemCat> queryWrapper = new QueryWrapper();
            queryWrapper.eq("parent_id",id);
            List twoIds = itemCatMapper.selectObjs(queryWrapper);
            //清空数据
            queryWrapper.clear();
            //规则: 如果2级菜单有值,才会删除 2级和三级
            queryWrapper.in(twoIds.size()>0,"parent_id",twoIds)
                        .or()
                        .in(twoIds.size()>0,"id",twoIds)
                        .or()
                        .eq("id",id);
            itemCatMapper.delete(queryWrapper);
        }
    }

5. 修改

5.1 状态修改操作

5.1.1 页面JS分析

1. 页面JS函数
updateStatus(scope.row)

2. 页面JS
 	  //根据ID修改状态信息
      async updateStatus(itemCat) {
    
    
        const {
    
    
          data: result
        } = await this.$http.put(`/itemCat/status/${
      
      itemCat.id}/${
      
      itemCat.status}`)
        if (result.status !== 200) return this.$message.error("修改状态失败")
        this.$message.success("状态修改成功")
      },

5.1.2 业务接口文档

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

5.1.3 编辑ItemCatController

/**
     * 实现商品分类状态修改
     * URL: /itemCat/status/{id}/{status}
     * 请求类型: PUT/POST
     * 请求参数: id/status
     * 返回值: SysResult对象
     */
    @PutMapping("/status/{id}/{status}")
    public  SysResult updateStatus(ItemCat itemCat){
    
    

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

5.1.4 编辑ItemCatService

	@Override
    @Transactional
    public void updateStatus(ItemCat itemCat) {
    
    //id/status
        itemCat.setUpdated(new Date());
        itemCatMapper.updateById(itemCat);
    }

5.2 商品分类修改操作

5.2.1 页面JS分析

	1.指定修改的按钮
	<el-button type="success" icon="el-icon-edit" @click="updateItemCatBtn(scope.row)">编辑</el-button>
	
	2. 数据的回显
	//由于有层级关系,所有修改只能修改名称
      updateItemCatBtn(itemCat) {
    
    
        this.updateItemCatForm = itemCat
        this.updateItemCatDialogVisible = true
      },

	3. 修改页面的JS
	<el-dialog title="修改商品分类" :visible.sync="updateItemCatDialogVisible" width="50%">
      <!-- 定义分类表单 -->
      <el-form :model="updateItemCatForm" :rules="rules" ref="upDateItemCatForm" label-width="100px">
        <el-form-item label="分类名称:" prop="name">
          <el-input v-model="updateItemCatForm.name"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="updateItemCatDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="updateItemCat">确 定</el-button>
      </span>
    </el-dialog>
     
     4. 修改按钮的JS
       async updateItemCat() {
    
    
        //修改商品分类信息
        const {
    
    data: result} =
          await this.$http.put('/itemCat/updateItemCat', this.updateItemCatForm)
        if (result.status !== 200) return this.$message.error("更新商品分类失败")
        this.$message.success("更新商品分类成功")
        this.findItemCatList();
        this.updateItemCatDialogVisible = false;
      },

5.2.2 页面接口文档

  • 请求路径: /itemCat/updateItemCat
  • 请求类型: put
  • 请求参数: 表单数据 ItemCat对象
  • 返回值: SysResult对象
参数名称 参数说明 备注
status 状态信息 200表示服务器请求成功
msg 服务器返回的提示信息 可以为null
data 服务器返回的业务数据 可以为null
  • 数据解析:
    在这里插入图片描述

5.2.3 编辑ItemCatController

/**
     * 修改商品分类名称
     * URL: /itemCat/updateItemCat
     * 参数: 整个form表单  JSON串
     * 返回值: SysResult对象
     */
    @PutMapping("/updateItemCat")
    public SysResult updateItemCat(@RequestBody ItemCat itemCat){
    
    

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

5.2.4 编辑ItemCatService

 //由于页面只修改的name名称.所以sql也只修改name/updated
    @Override
    @Transactional
    public void updateItemCat(ItemCat itemCat) {
    
    
        //用户只修改name,updated by id
        ItemCat temp = new ItemCat();
        temp.setId(itemCat.getId())
                .setName(itemCat.getName())
                .setUpdated(new Date());
        itemCatMapper.updateById(temp);
    }

5.3 debug断点调试

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43770110/article/details/121275307