苍穹外卖
- 1、 阿里云OSS
- 2、菜品分类查询
1、 阿里云OSS
工具类
package com.sky.utils;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
/**
* 文件上传
*
* @param bytes
* @param objectName
* @return
*/
public String upload(byte[] bytes, String objectName) {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 创建PutObject请求。
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
//文件访问路径规则 https://BucketName.Endpoint/ObjectName
StringBuilder stringBuilder = new StringBuilder("https://");
stringBuilder
.append(bucketName)
.append(".")
.append(endpoint)
.append("/")
.append(objectName);
log.info("文件上传到:{}", stringBuilder.toString());
return stringBuilder.toString();
}
}
属性类 可以通过在properties中根据前缀名称匹配到
package com.sky.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "sky.alioss")
@Data
public class AliOssProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
}
配置类 项目启动时把工具类加载进来 只有一个即可
package com.sky.config;
import com.sky.properties.AliOssProperties;
import com.sky.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.nio.charset.StandardCharsets;
/**
* @ClassName Myconfig
* @Description 配置类 用于构建阿里云文件上传工具类
* @Author lukcy
* @Date 2024/7/7 11:02
* @Version 1.0
*/
@Configuration
@Slf4j
public class Myconfig {
/**
* 返回工具类 只用创建一个就行
* @param aliOssProperties
* @return
*/
@Bean
@ConditionalOnMissingBean
public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
log.info("创建文件上传工具类:{}",aliOssProperties);
return new AliOssUtil(aliOssProperties.getEndpoint(),aliOssProperties.getAccessKeyId(),aliOssProperties.getAccessKeySecret(),aliOssProperties.getBucketName());
}
}
使用
package com.sky.controller.admin;
import com.sky.annotation.AutoFilled;
import com.sky.constant.MessageConstant;
import com.sky.result.Result;
import com.sky.utils.AliOssUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;
/**
* @ClassName CommonController
* @Description TODO
* @Author lukcy
* @Date 2024/7/7 10:46
* @Version 1.0
*/
@Api("通用接口")
@Slf4j
@RequestMapping("/admin/common")
@RestController
public class CommonController {
/**
* 文件上传
* @param file
* @return
*/
@Autowired
private AliOssUtil aliOssUtil;
@PostMapping("/upload")
public Result<String> upload(MultipartFile file){
try {
String originalFilename = file.getOriginalFilename();
String extension = null;
if (originalFilename != null) {
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) {
}
return Result.error(MessageConstant.UPLOAD_FAILED);
}
}
即可上传到服务器 并且将地址回显给前端 前端通过src就能显示照片了
2、菜品分类查询
/**
* 菜品分页查询
* @param dishPageQueryDTO
* @return
*/
@Override
public PageResult page(DishPageQueryDTO dishPageQueryDTO) {
PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());
Page<DishVO> page = dishMapper.page(dishPageQueryDTO);
return new PageResult(page.getTotal(), page.getResult());
}
主要前端需要的有一个分类名称 这是DIsh里边没有的,我们需要根据分类id找到分类名称,二表连接。
<select id="page" resultType="com.sky.vo.DishVO">
select d.*, c.name as categoryName from dish d left outer join category c on d.category_id = c.id
<where>
<if test="name != null">
and 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>
命名为categoryName 是因为我们的VO里就是该名称,mybatis可以帮我们set进去
package com.sky.vo;
import com.sky.entity.DishFlavor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DishVO implements Serializable {
private Long id;
//菜品名称
private String name;
//菜品分类id
private Long categoryId;
//菜品价格
private BigDecimal price;
//图片
private String image;
//描述信息
private String description;
//0 停售 1 起售
private Integer status;
//更新时间
private LocalDateTime updateTime;
//分类名称
private String categoryName;
//菜品关联的口味
private List<DishFlavor> flavors = new ArrayList<>();
//private Integer copies;
}
这里我本来使用的是这个方法
/**
* 菜品分页查询
* @param dishPageQueryDTO
* @return
*/
@Override
public PageResult page(DishPageQueryDTO dishPageQueryDTO) {
PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
//先获取DISH的基本信息
Page<Dish> page=dishMapper.page(dishPageQueryDTO);
long total = page.getTotal();
List<Dish> result = page.getResult();
//将分类名称给加上
List<DishVO> dishVOS=result.stream().map((item->{
DishVO dishVO=new DishVO();
BeanUtils.copyProperties(item,dishVO);
Long categoryId = item.getCategoryId();
String Cname=categoryMapper.getNameByCID(categoryId);
dishVO.setCategoryName(Cname);
return dishVO;
})).collect(Collectors.toList());
return new PageResult(total,dishVOS);
}
但是每个菜品都要查询一次数据库 查询名称 耗时
第一种方法 只用查询一次即可。