1.BaseTrademarkController(品牌管理CRUD)
/*** 添加品牌* @param baseTrademark* @return*/@PostMapping("baseTrademark/save")public Result<BaseTrademark> save(@RequestBody BaseTrademark baseTrademark){baseTrademarkService.save(baseTrademark);return Result.ok();}
/*** 品牌的主键查询* 请求参数品牌主键ID*/@GetMapping("baseTrademark/get/{id}")@Operation(summary = "品牌主键查询")public Result<BaseTrademark> findById(@PathVariable("id")Long id){BaseTrademark baseTrademark = baseTrademarkService.getById(id);return Result.ok(baseTrademark);}
/*** 修改品牌数据* 请求参数Json*/@Operation(summary = "修改品牌")@PutMapping("baseTrademark/update")public Result<BaseTrademark> update (@RequestBody BaseTrademark baseTrademark){baseTrademarkService.updateById(baseTrademark);return Result.ok();}
/*** 删除品牌数据* 请求参数,品牌的主键*/@Operation(summary = "删除品牌")@DeleteMapping("baseTrademark/remove/{id}")public Result<BaseTrademark> deleteById(@PathVariable("id") Long spuId){//不能直接被删除,调业务层逻辑功能baseTrademarkService.deleteById(spuId);return Result.ok();}
@Overridepublic void deleteById(Long spuId) {Long count= spuInfoMapper.selectCount(new QueryWrapper<SpuInfo>().eq("tm_id",spuId));System.out.println("count = " + count);//查询到总条数大于0,不能删除if (count > 0){//SpringMVC,全局的异常处理,抛出自定义的异常throw new MallException(ResultCodeEnum.REF_SPU_ERROR.getMessage(),ResultCodeEnum.REF_SPU_ERROR.getCode());}else {this.removeById(spuId);}}
后端程序产生异常以后,前端直接显示’已取消删除‘提示信息不友好
自定义异常
@Data
public class MallException extends RuntimeException{/*** 定义异常中的参数* 状态码,异常的消息*/private String message;private Integer code;public MallException(){}public MallException(String message, Integer code) {this.message = message;this.code = code;}
}
自定义全局异常处理器
/*** 全局的异常处理器* 捕获异常:@RestControllerAdvice注解的类可以捕获整个应用程序中抛出的异常。* 任何异常都由这个类处理*/
@RestControllerAdvice
public class GlobalExceptionHandler {/*** ExceptionHandler注解,捕获异常* @param e* @return*/@ExceptionHandler(value = MallException.class)public Result<Object> mallExceptionHandler(MallException e) {Result<Object> result = new Result<>();result.setCode(e.getCode());result.setMessage(e.getMessage());System.out.println("result = " + result);return result;}
}
SPU = Standard Product Unit (标准化产品单元), SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一
个产品的特性。通俗点讲就是泛指一类商品,这种商品具有相同的属性。
举例:
iPhone 16 小米15s Thinkpad 笔记本
SPU是定位到产品的概念,但它和产品细节无关。但实际上,我们在购买商品的时候,单凭SPU是不够的,还需要更多的信息来精确到可购买单元。
SKU = stock keeping unit(库存量单位) SKU即库存进出计量的单位(买家购买、商家进货、供应商备货、工厂生产都是依据SKU进行的)。是和具体的属性值有直
接的关联关系。SKU是物理上不可分割的最小存货单元。也就是说一款商品,可以根据SKU来确定具体的货物存量。
常见电商网站商品详情展示方式:
1、天猫:以spu展示
2、京东:以sku展示
不使用主外键,所以用spu和sku来确定能不能删除,当spu对应的有sku时,便不能删除
2.分页查询
/*** pageInfo* @param pageNumber* @param pageSize* @return*/@GetMapping("baseTrademark/{page}/{limit}")public Result<Page<BaseTrademark>> findTrademarkByPage(@PathVariable("page") Integer pageNumber, @PathVariable("limit") Integer pageSize){Page<BaseTrademark> page = baseTrademarkService.findTrademarkByPage(pageNumber,pageSize);System.out.println(page);return Result.ok(page);}
@Overridepublic Page<BaseTrademark> findTrademarkByPage(Integer pageNumber, Integer pageSize) {Page<BaseTrademark> baseTrademarkpage = new Page<>(pageNumber,pageSize);return page(baseTrademarkpage);}
具体使用是调用IService<T>的page方法
default <E extends IPage<T>> E page(E page) {return this.page(page, Wrappers.emptyWrapper());}
3 Minio
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.13</version>
</dependency>
测试用例:
public class MinioFileUploadTest {public static void main(String[] args) {//1.创建Minio客户端对象MinioClient minioClient = MinioClient.builder().endpoint("http://192.168.157.128:9000").credentials("admin","admin123456").build();//2.判断是否存在try {boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket("mall").build());if (!bucketExists){minioClient.makeBucket(MakeBucketArgs.builder().bucket("mall").build());}//3.上传文件FileInputStream fileInputStream = new FileInputStream("D:\\Apic\\1345360.png");minioClient.putObject(PutObjectArgs.builder().bucket("mall").object("1345360.png").stream(fileInputStream, fileInputStream.available(), -1).build());//4.获取访问地址String fileUrl = "http://192.168.157.128:9000/mall/1345360.png" ;System.out.println(fileUrl);} catch (ErrorResponseException e) {throw new RuntimeException(e);} catch (InsufficientDataException e) {throw new RuntimeException(e);} catch (InternalException e) {throw new RuntimeException(e);} catch (InvalidKeyException e) {throw new RuntimeException(e);} catch (InvalidResponseException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} catch (NoSuchAlgorithmException e) {throw new RuntimeException(e);} catch (ServerException e) {throw new RuntimeException(e);} catch (XmlParserException e) {throw new RuntimeException(e);}}
优化用例:
1.使用配置文件配置静态资源例如minio的地址,账号密码等
2.书写config,MinioClient用来判断是否有对应的桶,MinioProperty用来读取配置文件,配置文件写在启动类;
3.书写将文件上传代码解耦并抽出,增加复用性。
#minio连接配置 minio:url: http://192.168.157.128:9000accessKey: adminsecretKey: admin123456bucket: mall
@Data
@Configuration
public class MinioProperty {@Value("${minio.url}")private String url;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Value("${minio.bucket}")private String bucket;
}
@Configuration
public class MinioConfig {@AutowiredMinioProperty minioProperty;@Beanpublic MinioClient minioClient()throws Exception{//1.创建Minio客户端对象MinioClient minioClient = MinioClient.builder().endpoint(minioProperty.getUrl()).credentials(minioProperty.getAccessKey(), minioProperty.getSecretKey()).build();//2.判断Minio服务器中,是否存在桶,如果不存在,创建,方法bucketExists判断//方法的参数 BucketExistsArgs类型,返回true,有这个桶boolean bucketExists;BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(minioProperty.getBucket()).build();MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(minioProperty.getBucket()).build();if (!minioClient.bucketExists(bucketExistsArgs)){minioClient.makeBucket(makeBucketArgs);}return minioClient;}
}
以上代码关键就是BucketExistsArgs、MakeBucketArgs来判断桶存在和创建桶
@Bean可以将方法注入其他类进行调用;
@Component
public class FileUploadUtil {@Autowiredprivate MinioClient minioClient;@Autowiredprivate MinioProperty minioProperty;/*** 返回上传后的文件地址* 方法的参数,SpringMVC的上传对象*/public String fileUpload(MultipartFile multipartFile)throws Exception{//定义新的上传的文件名String originalFilename = multipartFile.getOriginalFilename();//上传的原始文件名//获取文件的后缀名String extension = FilenameUtils.getExtension(originalFilename);String fileName = UUID.randomUUID().toString().replace("-","")+"."+extension;//获取文件上传的字节输入流InputStream inputStream = multipartFile.getInputStream();//调用方法上传PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(minioProperty.getBucket()).object(fileName).stream(inputStream, inputStream.available(), -1).build();minioClient.putObject(putObjectArgs);//向controller返回文件的地址return minioProperty.getUrl()+"/"+minioProperty.getBucket()+"/"+fileName;}
}
/*** 实现文件的上传* 定义上传文件接口* multipartFile 接口名字必须和上传组件的name对应*/@PostMapping("fileUpload")public Result fileUpload(@RequestParam("file") MultipartFile multipartFile){System.out.println(multipartFile);String filename=baseTrademarkService.fileUpload(multipartFile);return Result.ok(filename);}
4.Swagger
<!--swagger-->
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.1.0</version>
</dependency>
代替postman的在线请求发送,一般对controller层使用,所以放在services的pom里面
/*** 一级分类的请求响应*/
//@CrossOrigin
@Tag(name = "一级分类管理")
@RestController
@RequestMapping("/admin/product")
public class BaseCategory1Controller {//注入业务层@Autowiredprivate BaseCategory1Service baseCategory1Service;/*** 查询方法,查询所有的一级分类*/@GetMapping("/getCategory1")@Operation(description = "查询所有的一级分类")public Result<List<BaseCategory1>> findAll(){List<BaseCategory1> baseCategory1List = baseCategory1Service.list();return Result.ok(baseCategory1List);}
}
swagger的描述要在后端书写