基于Springboot外卖系统17: 新增套餐模块+餐品信息回显+多数据表存储

1.1 新增套餐需求分析

后台系统中可以管理套餐信息,通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐。

1.2 新增套餐数据模型

新增套餐,其实就是将新增页面录入的套餐信息插入到setmeal表,还需要向setmeal_dish表插入套餐和菜品关联数据。所以在新增套餐时,涉及到两个表:

说明备注
setmeal套餐表存储套餐的基本信息
setmeal_dish套餐菜品关系表存储套餐关联的菜品的信息(一个套餐可以关联多个菜品)

1). 套餐表setmeal

在该表中,套餐名称name字段是不允许重复的,在建表时,已经创建了唯一索引。

2). 套餐菜品关系表setmeal_dish

在该表中,菜品的名称name,菜品的原价price 实际上都是冗余字段,因为在这张表中存储了菜品的ID(dish_id),根据该ID就可以查询出name与price的数据信息,而这里又存储了name,price。在后续的查询展示操作中,就不需要再去查询数据库获取菜品名称和原价了,这样可以简化操作。

1.3 新增套餐准备工作

在开发业务功能前,先将需要用到的类和接口基本结构创建好,无需准备Setmeal的相关实体类、Mapper接口、Service接口及实现,因为之前在做分类管理的时候,已经引入了Setmeal的相关基础代码。 接下来,我们就来完成以下的几步准备工作:

 1). 实体类 SetmealDish

package com.itheima.reggie.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;/*** 套餐菜品关系*/
@Data
public class SetmealDish implements Serializable {private static final long serialVersionUID = 1L;private Long id;//套餐idprivate Long setmealId;//菜品idprivate Long dishId;//菜品名称 (冗余字段)private String name;//菜品原价private BigDecimal price;//份数private Integer copies;//排序private Integer sort;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)private Long updateUser;//是否删除private Integer isDeleted;
}

2). DTO SetmealDto

该数据传输对象DTO,主要用于封装页面在新增套餐时传递过来的json格式的数据,其中包含套餐的基本信息,还包含套餐关联的菜品集合。

package com.itheima.reggie.dto;import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import lombok.Data;
import java.util.List;@Data
public class SetmealDto extends Setmeal {private List<SetmealDish> setmealDishes;private String categoryName;
}

3). Mapper接口 SetmealDishMapper

package com.itheima.reggie.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.SetmealDish;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface SetmealDishMapper extends BaseMapper<SetmealDish> {
}

 4). 业务层接口 SetmealDishService

package com.itheima.reggie.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.SetmealDish;public interface SetmealDishService extends IService<SetmealDish> {}

5). 业务层实现类 SetmealDishServiceImpl

package com.itheima.reggie.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.SetmealDishMapper;
import com.itheima.reggie.service.SetmealDishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;/*** Description: new java files header..** @author w* @version 1.0* @date 2022/8/19 15:35*/
@Service
@Slf4j
public class SetmealDishServiceImpl extends ServiceImpl<SetmealDishMapper, SetmealDish> implements SetmealDishService {}

6). 控制层 SetmealController

套餐管理的相关业务,我们都统一在 SetmealController 中进行统一处理操作。

package com.itheima.reggie.controller;import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** Description: 套餐管理* @version 1.0* @date 2022/8/19 15:37*/@RestController
@RequestMapping("/setmeal")
@Slf4j
public class SetmealController {@Autowiredprivate SetmealService setmealService;@Autowiredprivate SetmealDishService setmealDishService;@PostMappingpublic R<String> save(@RequestBody SetmealDto setmealDto){/**@Description: 新增套餐* @version v1.0* @author LiBiGo* @date 2022/8/19 16:04*/log.info("套餐信息:{}",setmealDto);setmealService.saveWithDish(setmealDto);return R.success("新增套餐成功");}}

1.4 新增套餐时前端页面和服务端的交互过程

1). 点击新建套餐按钮,访问页面(backend/page/combo/add.html),页面加载发送ajax请求,请求服务端获取套餐分类数据并展示到下拉框中(==已实现==)

获取套餐分类列表的功能我们不用开发,之前已经开发完成了,之前查询时type传递的是1,查询菜品分类; 本次查询时,传递的type为2,查询套餐分类列表。

2). 访问页面(backend/page/combo/add.html),页面加载时发送ajax请求,请求服务端获取菜品分类数据并展示到添加菜品窗口中(==已实现==)

本次查询分类列表,传递的type为1,表示需要查询的是菜品的分类。查询菜品分类的目的,是添加套餐关联的菜品时,我们需要根据菜品分类,来过滤查询菜品信息。查询菜品分类列表的代码已经实现, 具体展示效果如下:

 3). 当点击添加菜品窗口左侧菜单的某一个分类, 页面发送ajax请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中

4). 页面发送请求进行图片上传,请求服务端将图片保存到服务器(==已实现==)

5). 页面发送请求进行图片下载,将上传的图片进行回显(==已实现==)

 6). 点击保存按钮,发送ajax请求,将套餐相关数据以json形式提交到服务端

经过上述的页面解析及流程分析,发送这里需要发送的请求有5个,分别是 :

A. 根据传递的参数,查询套餐分类列表(已实现)

B. 根据传递的参数,查询菜品分类列表(已实现)

C. 图片上传(已实现)

D. 图片下载展示(已实现)

E. 根据菜品分类ID,查询菜品列表

1.5 新增套餐需要开发的功能

1). 根据分类ID查询菜品列表

请求说明
请求方式GET
请求路径/dish/list
请求参数?categoryId=1397844263642378242

2). 保存套餐信息

请求说明
请求方式POST
请求路径/setmeal
请求参数json格式数据

传递的json格式数据如下:

{"name":"营养超值工作餐","categoryId":"1399923597874081794","price":3800,"code":"","image":"9cd7a80a-da54-4f46-bf33-af3576514cec.jpg","description":"营养超值工作餐","dishList":[],"status":1,"idType":"1399923597874081794","setmealDishes":[{"copies":2,"dishId":"1423329009705463809","name":"米饭","price":200},{"copies":1,"dishId":"1423328152549109762","name":"可乐","price":500},{"copies":1,"dishId":"1397853890262118402","name":"鱼香肉丝","price":3800}]
}

1.6 根据分类查询菜品--代码开发

1.5.1 根据分类查询菜品

在当前的需求中,只需要根据页面传递的菜品分类的ID(categoryId)来查询菜品列表即可,因此直接定义一个DishController的方法,声明一个Long类型的categoryId,这样做是没问题的。

但是考虑到该方法的拓展性,我们在这里定义方法时,通过Dish这个实体来接收参数。

在DishController中定义方法list,接收Dish类型的参数:

在查询时,需要根据菜品分类categoryId进行查询,并且还要限定菜品的状态为起售状态(status为1),然后对查询的结果进行排序。

package com.itheima.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;
import java.util.stream.Collectors;/*** Description: 菜品管理 菜品及菜品口味的相关操作,统一使用这一个controller即可。* @version 1.0* @date 2022/8/18 11:08*/@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {@Autowiredprivate DishService dishService;@Autowiredprivate DishFlavorService dishFlavorService;@Autowiredprivate CategoryService categoryService;@PostMappingpublic R<String> save(@RequestBody DishDto dishDto){/**@Description: 新增菜品* @author LiBiGo* @date 2022/8/18 11:44*/log.info(dishDto.toString());dishService.saveWithFlavor(dishDto);return R.success("新增菜品成功");}@GetMapping("/page")public R<Page> page(int page,int pageSize,String name){/**@Description: 菜品信息分页查询* @author LiBiGo** 数据库查询菜品信息时,获取到的分页查询结果 Page 的泛型为 Dish,而最终需要给前端页面返回的类型为DishDto,* 所以这个时候就要进行转换,基本属性直接通过属性拷贝的形式对Page中的属性进行复制,* 对于结果列表 records属性需要进行特殊处理的(需要封装菜品分类名称);** @date 2022/8/19 10:41*/// 构造分页构造器对象Page<Dish> pageInfo = new Page<>(page,pageSize);Page<DishDto> dishDtoPage = new Page<>();// 条件构造器LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();// 添加过滤条件queryWrapper.like(name!=null,Dish::getName,name);// 添加排序条件queryWrapper.orderByDesc(Dish::getUpdateTime);// 执行分页查询dishService.page(pageInfo,queryWrapper);// 对象的拷贝BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");List<Dish> records = pageInfo.getRecords();List<DishDto> list = records.stream().map((item) -> {DishDto dishDto = new DishDto();BeanUtils.copyProperties(item,dishDto);Long categoryId = item.getCategoryId();//分类id//根据id查询分类对象Category category = categoryService.getById(categoryId);if(category != null){String categoryName = category.getName();dishDto.setCategoryName(categoryName);}return dishDto;}).collect(Collectors.toList());dishDtoPage.setRecords(list);return R.success(dishDtoPage);}@GetMapping("/{id}")public R<DishDto> get(@PathVariable Long id){/**@Description: 根据id查询菜品信息和对应的口味信息* @author LiBiGo* @date 2022/8/19 11:43*/DishDto dishDto = dishService.getByIdWithFlavor(id);return R.success(dishDto);}@PutMapping// @PathVariable : 该注解可以用来提取url路径中传递的请求参数。public R<String> update(@RequestBody DishDto dishDto){/**@Description: 修改菜品* @author LiBiGo* @date 2022/8/19 11:58*/log.info(dishDto.toString());dishService.updateWithFlavor(dishDto);return R.success("新增菜品成功");}@GetMapping("/list")public R<List<Dish>> list(Dish dish){/**@Description: 根据条件查询对应的菜品数* @author LiBiGo* @date 2022/8/19 15:49*/// 构造查询条件LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());//添加条件,查询状态为1(起售状态)的菜品queryWrapper.eq(Dish::getStatus,1);//  添加排序条件queryWrapper.orderByDesc(Dish::getSort).orderByDesc(Dish::getUpdateTime);List<Dish> list = dishService.list(queryWrapper);return R.success(list);}}

1.5.2 根据分类查询菜品功能测试

代码编写完毕,我们重新启动服务器,进行测试,可以通过debug断点跟踪的形式查看页面传递的参数封装情况,及响应给页面的数据信息。

1.7 保存套餐功能--代码开发

1.7.1 逻辑分析

在进行套餐信息保存时,前端提交的数据,不仅包含套餐的基本信息,还包含套餐关联的菜品列表数据 setmealDishes。

解决方案:需要在Setmeal的基本属性的基础上,再扩充一个属性 setmealDishes来接收页面传递的套餐关联的菜品列表,

1). SetmealController中定义方法save,新增套餐

package com.itheima.reggie.controller;import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** Description: 套餐管理* 不仅需要保存套餐的基本信息,还需要保存套餐关联的菜品数据,所以需要再该方法中调用业务层方法,完成两块数据的保存。* @version 1.0* @date 2022/8/19 15:37*/@RestController
@RequestMapping("/setmeal")
@Slf4j
public class SetmealController {@Autowiredprivate SetmealService setmealService;@Autowiredprivate SetmealDishService setmealDishService;@PostMapping// 页面传递的数据是json格式,需要在方法形参前面加上@RequestBody注解, 完成参数封装。public R<String> save(@RequestBody SetmealDto setmealDto){/**@Description: 新增套餐* @version v1.0* @author LiBiGo* @date 2022/8/19 16:04*/log.info("套餐信息:{}",setmealDto);setmealService.saveWithDish(setmealDto);return R.success("新增套餐成功");}}

 2). SetmealService中定义方法saveWithDish

package com.itheima.reggie.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Setmeal;public interface SetmealService extends IService<Setmeal> {// 新增套餐,同时需要保存套餐和菜品的关联关系public void saveWithDish(SetmealDto setmealDto);
}

3). SetmealServiceImpl实现方法saveWithDish

package com.itheima.reggie.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;
import java.util.stream.Collectors;/*** Description: new java files header..** @author w* @version 1.0* @date 2022/8/16 10:17*/
@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {@Autowiredprivate SetmealDishService setmealDishService ;@Transactional@Overridepublic void saveWithDish(SetmealDto setmealDto) {/**@Description: 新增套餐,同时需要保存套餐和菜品的关联关系** A. 保存套餐基本信息* B. 获取套餐关联的菜品集合,并为集合中的每一个元素赋值套餐ID(setmealId)* C. 批量保存套餐关联的菜品集合** @author LiBiGo* @date 2022/8/19 16:10*/// 保存套餐的基本信息,操作setmeal,执行insert操作this.save(setmealDto);List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();setmealDishes.stream().map((item) -> {item.setSetmealId(setmealDto.getId());return item;}).collect(Collectors.toList());// 保存套餐和菜品的关联信息,操作setmeal_dish,执行insert操作setmealDishService.saveBatch(setmealDishes);}
}

1.7.2 功能测试

代码编写完毕,重新启动服务器,进行测试,可以通过debug断点跟踪的形式查看页面传递的参数封装情况及套餐相关数据的保存情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cocoscreator editbox 只允许数字_用Cocos做一个数字调节框

点击上方蓝色字关注我们~当玩家购买道具的时候&#xff0c;一个个买可能会比较麻烦&#xff0c;用数字调节框的话玩家一次性就可以买好几十个了(钱够的话)。运行效果如下&#xff1a;Cocos Creator版本&#xff1a;2.2.0后台回复"数字调节框"&#xff0c;获取该项目完…

Xshell 无法连接虚拟机中的ubuntu的问题

转自&#xff1a;http://blog.csdn.net/qq_26941173/article/details/51173320版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 昨天在VMware Player中安装了ubuntu系统&#xff0c;今天想通过xshell连接ubuntu&#xff0c;结果显示 Connecting t…

基于Springboot外卖系统18:套餐分页查询模块+删除套餐+多数据表同步

1. 套餐分页查询模块 1.1 需求分析 系统中的套餐数据很多的时候&#xff0c;如果在一个页面中全部展示出来会显得比较乱&#xff0c;不便于查看&#xff0c;所以一般的系统中都会以分页的方式来展示列表数据。 在进行套餐数据的分页查询时&#xff0c;除了传递分页参数以外&a…

jsp项目开发案例_Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)life...

1 开发需要环境工欲善其事&#xff0c;必先利其器。在正式开发之前我们检查好需要安装的拓展&#xff0c;不要开发中发现这些问题&#xff0c;打断思路影响我们的开发效率。安装 swoole 拓展包安装 redis 拓展包安装 laravel5.5 版本以上如果你还不会用swoole就out了程序猿的生…

Docker系列第01部分:介绍+虚拟化+什么是Decker+组件

0 应用部署难点 1.在软件开发中&#xff0c;最麻烦的事情之一就是环境配置。在正常情况下&#xff0c;如果要保证程序能运行&#xff0c;我们需要设置好操作系统&#xff0c;以及各种库和组件的安装。2.举例来说&#xff0c;要运行一个Python程序&#xff0c;计算机必须要有 P…

1.7.08:字符替换

08:字符替换 查看提交统计提问总时间限制: 1000ms内存限制: 65536kB描述把一个字符串中特定的字符全部用给定的字符替换&#xff0c;得到一个新的字符串。 输入只有一行&#xff0c;由一个字符串和两个字符组成&#xff0c;中间用单个空格隔开。字符串是待替换的字符串&#xf…

net.conn read 判断数据读取完毕_1.5 read, write, exit系统调用

接下来&#xff0c;我将讨论对于应用程序来说&#xff0c;系统调用长成什么样。因为系统调用是操作系统提供的服务的接口&#xff0c;所以系统调用长什么样&#xff0c;应用程序期望从系统调用得到什么返回&#xff0c;系统调用是怎么工作的&#xff0c;这些还是挺重要的。你会…

Docker系列第02部分:Docker安装与启动

1 安装环境说明 这里将Docker安装到CentOS上。注意&#xff1a;这里建议安装在CentOS7.x以上的版本&#xff0c;在CentOS6.x的版本中&#xff0c;安装前需要安装其他很多的环境而且Docker很多补丁不支持更新。 2 Docker安装与使用 2.0 windows安装 1 windows安装&#xff08…

Docker系列第03部分:列出镜像+搜索镜像+拉取镜像+删除镜像

1.什么是Docker镜像 Docker镜像是由文件系统叠加而成&#xff08;是一种文件的存储形式&#xff09;。最底端是一个文件引导系统&#xff0c;即bootfs&#xff0c;这很像典型的Linux/Unix的引导文件系统。Docker用户几乎永远不会和引导系统有什么交互。实际上&#xff0c;当一…

c语言sort函数_C语言的那些经典程序 第八期

戳“在看”一起来充电吧!C语言的那些经典程序 第八期上期带大家欣赏的指针经典程序&#xff0c;感觉如何&#xff1f;这期我们准备了几个新指针的内容&#xff0c;灵活运用指针可以大大减少程序的复杂度&#xff0c;接下来就让小C来说说这三个有关指针应用的经典程序吧&#xf…

Docker系列第04部分:查看容器+创建容器+启动容器+文件挂载+删除容器

1 容器的创建和启动 1.1 虚拟机的生命周期 1.2 容器的生命周期 2、容器操作 2.1 查看容器 查看正在运行容器&#xff1a; docker ps 查看所有的容器&#xff08;启动过的历史容器&#xff09; docker ps –a 查看最后一次运行的容器&#xff1a; docker ps -l 查看停止的容…

java程序设计及实践实践代码_杭+新闻:姚争为老师把程序设计讲“活”了,满是代码的枯燥课程被学生“秒杀”...

通讯员 陈鑫 杨鹏飞记者 方秀芬作为专业选修课&#xff0c;Java程序设计和Web程序设计&#xff0c;这两门满是代码的课程&#xff0c;看似很枯燥&#xff0c;但在杭师大信息科学与工程学院却爆红&#xff0c;每学期都遭“秒杀”&#xff0c;以前线下课&#xff0c;提前20分钟准…

Docker系列第05部分:实战部署应用全流程

1 MySQL部署 1.1拉取MySQL镜像 docker pull mysql 查看镜像&#xff1a; 1.2创建MySQL容器 docker run -di --namepinyougou_mysql -p 33306:3306 -e MYSQL_ROOT_PASSWORD123456 mysql:5.7 # -p 代表端口映射&#xff0c;格式为 宿主机映射端口:容器运行端口 # -e 代表添加…

Vim安装插件在命令行下看代码

这几天我又想抛弃source insight 了&#xff0c;主要是太慢了 安装如下 VIM万能插件 或者使用 sudo apt-get installexuberant-ctags 安装 我主要是使用函数跳转功能&#xff0c;需要记住几个指令 1、生成tags用来实现函数跳转 这样会生成一个tags文件&#xff0c;作为跳…

Docker系列第06部分:备份与迁移+dockerfile

1 备份与迁移 1.1 容器保存为镜像 docker commit pinyougou_nginx mynginx# pinyougou_nginx是容器名称 # mynginx是新的镜像名称 # 此镜像的内容就是你当前容器的内容&#xff0c;接下来你可以用此镜像再次运行新的容器1.2 镜像备份 docker save -o mynginx.tar mynginx #…

流浪地球开机动画包zip_影视日报|合家欢动画电影quot;许愿神龙quot;定档1.15;流浪地球加长版定档11.26...

1、合家欢动画电影"许愿神龙"定档1.15动画电影《许愿神龙》正式定档2021年1月15日&#xff0c;并发布定档海报。2、白客等万万兄弟助力易小星"沐浴之王"由易小星执导&#xff0c;彭昱畅、乔杉领衔主演&#xff0c;卜冠今、苇青主演&#xff0c;金世佳友情出…

Git 分布式版本控制工具01:Git介绍+下载+安装

1. 前言 1.1 什么是Git Git 是一个分布式版本控制工具&#xff0c;通过Git 仓库来存储和管理源代码文件文件。 在IDEA开发工具中可以集成Git&#xff1a; 集成后在IDEA中可以看到Git相关图标&#xff1a; 可以通过启动两个IDEA窗口模拟两个开发人员来展示Git的使用&#xf…

无法解析的外部符号,无法解析的外部命令

1.这个是因为有相关的lib包没有被引用进去 解决办法&#xff1a; 1. 2. 转载于:https://www.cnblogs.com/hcfan/p/6638980.html

Android Adb 源码分析

扭起屁股得意洋洋 最近&#xff0c;我负责的项目因为临近量产&#xff0c;把之前的userdebug版本关闭&#xff0c;转成了user版本&#xff0c;增加selinux的权限&#xff0c;大家都洋溢在项目准备量产的兴奋和喜悦之中不能自拔 谁知&#xff0c;好景不长&#xff0c;user版本…

kvm虚拟化_KVM 虚拟化环境搭建 - WebVirtMgr

前文《KVM 虚拟化环境搭建 - ProxmoxVE》已经给大家介绍了开箱即用的 PVE 系统&#xff0c;PVE 是方便&#xff0c;但还是有几点问题&#xff1a;第一&#xff1a;始终是商用软件&#xff0c;虽然可以免费用&#xff0c;但未来版本还免费么&#xff1f;商用的法律风险呢&#x…