- 创建阿里云oss 先申请账号 开通oss 然后创建bucket 名字随便起 然后需要开启本地冗余存储 并且创建完之后读写权限设置为公共读
然后endpoint 是bucket下概览中的外网访问 其他的bucket-name 和secret 以及id都是之前保存的 在密码.txt中 然后具体实现就是调用工具类upload方法 一个是文件的byte数组参数 一个就是文件名 需要注意的是 文件名上传到阿里云服务器 如果是重名的话会覆盖掉 因此就需要用到UUID来确保文件名是唯一的 不会被覆盖掉 第一步就是得到文件原始名 然后截取出来扩展名 再定义一个UUID 然后拼接上扩展名 最后传入到upload 方法中就可以了 代码如下
@Autowired
AliOssUtil aliOssUtil;
@PostMapping("/upload")
@ApiOperation("文件上传")
public Result<String> upload(MultipartFile file) {
log.info("文件上传,{}", file);
try {
//拿到原始文件名
String originalFilename = file.getOriginalFilename();
//拿到扩展名
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
//构造新文件名 保证不重名把之前的覆盖掉
String objectName = UUID.randomUUID().toString() + extension;
//文件的请求路径
String filePath = aliOssUtil.upload(file.getBytes(),objectName);
return Result.success(filePath);
} catch (IOException e) {
log.error("文件上传失败",e);
}
return Result.error(MessageConstant.UPLOAD_FAILED);
}
- 新增菜品和口味 这个接口涉及到两个表 一个是菜品表 一个是口味表 因此需要添加
@Transactional'来进行事务操作 然后主要分为两步 第一步是先插入菜品 因为前端传过来是DTO对象 其中包括口味 因此需要重新定义对象dish 然后把DTO数据对拷给dish对象 然后调用service方法进行插入 需要注意的是插入完之后因为这个是插入方法 dish对象中有创建时间 修改时间创建人修改人的公共字段 所以需要在mapper方法上添加@AutoFill(OprationType.INSERT)来进行insert方法的自动填充 还需要注意的是 在插入之后 因为前端没有传过来id 而且后续插入口味表是需要菜品id的 所以在mapper中就需要设置useGenerateKeys = true来得到自增的菜品id 然后再用keyProperty = "id"`来将自增的dishId赋给dish对象中的id属性 然后就可以在service中得到这个id属性了 得到了id之后遍历flavors口味数组 对每一个口味都进行设置值 就可以将口味的菜品id设置成功
在插入口味的时候 因为传过来的是一个数组 因此就需要批量插入 而批量插入的mapper方法是使用标签 代码如下
<insert id="insertBatch">
insert into dish_flavor (dish_id, name, value) VALUES
<foreach collection="flavors" item="flavor" separator=",">
(#{flavor.dishId},#{flavor.name},#{falvor.value})
</foreach>
</insert>
- 新增菜品 个人感觉跟新增员工差不多 但是查询是多表查询 使用了左连接left join进行查询 然后对查询的表起个名字 并且用on来确定两个表之间的关系 然后避免菜品表中的name和分类表中的name重复 在查询的时候给分类表的name取一个别名 因此就可以完成查询操作 其他的比如分页都是跟查询员工一样的 该调用PageHelper.start开始就调用 该封装对象就封装还有一个不太一样的就是因为是要返回的是两个表中的值 因此需要一个专门的vo对象来对查询的结果进行封装 然后再交给controller进行R对象的返回
select d.*,c.name category_name from dish d left join category c on d.category_id = c.id
<where>
<if test="name != null">
d.name like concat('%',#{name},'%')
</if>
<if test="categoryId != null">
and d.category_id = #{categoryId}
</if>
<if test="status != null">
and d.status = #{status}
</if>
</where>
order by d.create_time desc
</select>
- 查询菜品和对应的口味数据 这个其实实现也比较容易实现 就是分为两步 先根据id查询菜品的基本信息 然后再根据id查询菜品的口味信息 最后用vo对象把这两个封装起来 业务代码就是
public DishVO getByIdWithFlavor(Long id) {
//根据id查询菜品数据
Dish dish = dishMapper.getById(id);
//根据菜品id查询口味数据
List<DishFlavor> dishFlavors = dishFlavorMapper.getByDishId(id);
//封装到vo
DishVO dishVO = new DishVO();
BeanUtils.copyProperties(dish,dishVO);
dishVO.setFlavors(dishFlavors);
return dishVO;
}
- 修改菜品 修改菜品分为两部分 一部分是修改菜品的基本信息 一部分是修改菜品的口味数据 因此需要修改两个表 基本信息表就是一个基础的动态sql就能解决了 而修改菜品的口味数据分为很多情况 比如不修改 比如新增 比如删除 比如先新增后删除 因此如果这样实现比较麻烦 就可以用另一种方式实现 当前端传过来数据时 先删除口味数据 然后再新增口味数据 这样就容易实现 完整的业务代码为
/**
* 根据id修改菜品基本信息和对应的口味信息
* @param dishDTO
*/
@Override
public void updateWithFlavor(DishDTO dishDTO) {
Dish dish = new Dish();
BeanUtils.copyProperties(dishDTO,dish);
//修改菜品表基本信息
dishMapper.update(dish);
//删除原有的口味数据
dishFlavorMapper.deleteByDishId(dishDTO.getId());
//再重新插入新的口味数据
List<DishFlavor> flavors = dishDTO.getFlavors();
if(flavors != null && flavors.size() > 0){
flavors.forEach(flavor -> {
flavor.setDishId(dishDTO.getId());
});
dishFlavorMapper.insertBatch(flavors);
}
}