个人博客项目笔记_08

bug修正

文章归档:

select FROM_UNIXTIME(create_date/1000,'%Y') as year, FROM_UNIXTIME(create_date/1000,'%m') as month,count(*) as count from ms_article group by year,month

1. 文章图片上传

1.1 接口说明

接口url:/upload

请求方式:POST

请求参数:

参数名称参数类型说明
imagefile上传的文件名称

返回数据:

{"success":true,"code":200,"msg":"success","data":"https://static.cherr.com/aa.png"
}
<dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>[7.13.0, 7.13.99]</version>
</dependency>

1.2 Controller

String fileName = UUID.randomUUID().toString() + “.” + StringUtils.substringAfterLast(originalFilename, “.”);

这行代码的作用是生成一个唯一的文件名,用于保存上传的文件。

  1. UUID.randomUUID().toString(): 这个方法调用生成一个随机的 UUID(Universally Unique Identifier),并将其转换为字符串形式。UUID 是一种用于唯一标识信息的标准化方法,通常由 32 个十六进制数字组成,例如:“550e8400-e29b-41d4-a716-446655440000”。使用 toString() 方法将其转换为字符串。
  2. "." + StringUtils.substringAfterLast(originalFilename, "."): 这部分代码是获取上传文件的扩展名,并将其与随机生成的 UUID 字符串拼接起来。StringUtils.substringAfterLast(originalFilename, ".") 方法从原始文件名中获取最后一个点 (.) 后面的字符串,即文件的扩展名。然后再在扩展名前面添加一个点,用于连接随机生成的 UUID。

通过这两个步骤,就可以生成一个形如 “random_uuid.png” 的唯一文件名,其这样可以确保每个上传的文件都有一个唯一的文件名,避免文件名冲突。

package com.cherriesovo.blog.controller;import com.cherriesovo.blog.utils.QiniuUtils;
import com.cherriesovo.blog.vo.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.util.UUID;@RestController
@RequestMapping("upload")
public class UploadController {@Autowiredprivate QiniuUtils qiniuUtils;@PostMappingpublic Result upload(@RequestParam("image") MultipartFile file){//原始文件名称 比如:1.pngString originalFilename = file.getOriginalFilename();//唯一的文件名称String fileName = UUID.randomUUID().toString() + "." + StringUtils.substringAfterLast(originalFilename, ".");//上传文件到哪里?七牛云 云服务器按量付费,速度快,把图片发到离用户最近的服务器//降低我们自身应用服务器的带宽消耗boolean upload = qiniuUtils.upload(file, fileName);if (upload){//QiniuUtils.url 是一个用于存储七牛云存储的 URL 地址的变量return Result.success(QiniuUtils.url + fileName);}return Result.fail(20001,"上传失败");}
}

1.3 使用七牛云

# 上传文件总的最大值
spring.servlet.multipart.max-request-size=20MB
# 单个文件的最大值
spring.servlet.multipart.max-file-size=2MB

需要自行修改的配置:

	//七牛云url或者自己的url(这里使用七牛云的url)public static  final String url = "http://sbf25hzn6.hb-bkt.clouddn.com/";//AK@Value("")private  String accessKey;//SK@Value("")private  String accessSecretKey;//对象空间名称String bucket = "cherriesovo-blog";
package com.cherriesovo.blog.utils;import com.alibaba.fastjson.JSON;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;@Component
public class QiniuUtils {//七牛云url或者自己的urlpublic static  final String url = "http://sbf25hzn6.hb-bkt.clouddn.com/";//AK@Value("")private  String accessKey;//SK@Value("")private  String accessSecretKey;//将文件上传到七牛云存储中//MultipartFile 是 Spring Framework 提供的一个接口,用于表示 HTTP 请求中的文件。在这段代码中,MultipartFile 类型的参数 file 用于接收客户端上传的文件。public  boolean upload(MultipartFile file,String fileName){//创建一个配置类对象 cfg,并指定了上传的区域为华北Configuration cfg = new Configuration(Region.huabei());//创建一个上传管理器对象 uploadManager,用于执行文件上传操作UploadManager uploadManager = new UploadManager(cfg);//...生成上传凭证,然后准备上传,(对象空间名称)String bucket = "cherriesovo-blog";//默认不指定key的情况下,以文件内容的hash值作为文件名try {byte[] uploadBytes = file.getBytes();//使用 MultipartFile 对象的 getBytes() 方法获取上传文件的字节数组Auth auth = Auth.create(accessKey, accessSecretKey);//创建一个认证对象String upToken = auth.uploadToken(bucket);//用认证对象的 uploadToken 方法生成上传凭证 upTokenResponse response = uploadManager.put(uploadBytes, fileName, upToken);//执行文件上传//解析上传成功的结果,将上传结果的 JSON 字符串解析为 DefaultPutRet 类对象 putRetDefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);return true;	//返回 true 表示上传成功} catch (Exception ex) {ex.printStackTrace();}return false;}
}

1.4 测试

2. 导航-文章分类

2.1 查询所有的文章分类

2.1.1 接口说明

接口url:/categorys/detail

请求方式:GET

请求参数:

参数名称参数类型说明

返回数据:

{"success": true, "code": 200, "msg": "success", "data": [{"id": 1, "avatar": "/static/category/front.png", "categoryName": "前端", "description": "前端是什么,大前端"}, {"id": 2, "avatar": "/static/category/back.png", "categoryName": "后端", "description": "后端最牛叉"}, {"id": 3, "avatar": "/static/category/lift.jpg", "categoryName": "生活", "description": "生活趣事"}, {"id": 4, "avatar": "/static/category/database.png", "categoryName": "数据库", "description": "没数据库,啥也不管用"}, {"id": 5, "avatar": "/static/category/language.png", "categoryName": "编程语言", "description": "好多语言,该学哪个?"}]
}
package com.cherriesovo.blog.vo;
import lombok.Data;@Data
public class CategoryVo {private Long id;private String avatar;private String categoryName;private String description;
}

2.1.2 Controller

@RestController
@RequestMapping("categorys")
public class CategoryController {@GetMapping("detail")public Result categoriesDetail(){return categoryService.findAllDetail();}}

2.1.3 Service

CategoryService:

Result findAllDetail();

CategoryServiceImpl:

 @Overridepublic Result findAll() {LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.select(Category::getId,Category::getCategoryName);//SELECT id, category_name FROM category;List<Category> categories = categoryMapper.selectList(queryWrapper);return Result.success(copyList(categories));}@Overridepublic Result findAllDetail() {//SELECT * FROM category;List<Category> categories = categoryMapper.selectList(new LambdaQueryWrapper<>());//页面交互的对象return Result.success(copyList(categories));}

2.2 查询所有的标签

2.2.1 接口说明

接口url:/tags/detail

请求方式:GET

请求参数:

参数名称参数类型说明

返回数据:

{"success": true, "code": 200, "msg": "success", "data": [{"id": 5, "tagName": "springboot", "avatar": "/static/tag/java.png"}, {"id": 6, "tagName": "spring", "avatar": "/static/tag/java.png"}, {"id": 7, "tagName": "springmvc", "avatar": "/static/tag/java.png"}, {"id": 8, "tagName": "11", "avatar": "/static/tag/css.png"}]
}

2.2.3 Controller

package com.cherriesovo.blog.vo;import lombok.Data;@Data
public class TagVo {private Long id;private String tagName;private String avatar;
}
@RestController
@RequestMapping("tags")
public class TagsController {@GetMapping("detail")public Result findAllDetail(){return tagsService.findAllDetail();}
}

2.2.4 Service

TagsService:

Result findAllDetail();//查询所有的标签

TagsServiceImpl:

	@Overridepublic Result findAll() {LambdaQueryWrapper<Tag> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.select(Tag::getId,Tag::getTagName);List<Tag> tags = this.tagMapper.selectList(queryWrapper);return Result.success(copyList(tags));}@Overridepublic Result findAllDetail() {LambdaQueryWrapper<Tag> queryWrapper = new LambdaQueryWrapper<>();//select * from tagList<Tag> tags = this.tagMapper.selectList(queryWrapper);return Result.success(copyList(tags));}

3. 分类文章列表

3.1 接口说明

接口url:/category/detail/{id}

请求方式:GET

请求参数:

参数名称参数类型说明
id分类id路径参数

返回数据:

{"success": true, "code": 200, "msg": "success", "data": {"id": 1, "avatar": "/static/category/front.png", "categoryName": "前端", "description": "前端是什么,大前端"}
}

3.2 Controller

CategoryController:

  @GetMapping("detail/{id}")public Result categoriesDetailById(@PathVariable("id") Long id){return categoryService.categoriesDetailById(id);}

3.3 Service

CategoryService:

Result categoriesDetailById(Long id);

CategoryServiceImpl:

@Overridepublic Result categoriesDetailById(Long id) {Category category = categoryMapper.selectById(id);CategoryVo categoryVo = copy(category);return Result.success(categoryVo);}

ArticleServiceImpl:

新增如下代码:

​ //查询文章的参数 加上分类id,判断不为空 加上分类条件
​ if (pageParams.getCategoryId() != null) {
​ queryWrapper.eq(Article::getCategoryId,pageParams.getCategoryId());
​ }

@Overridepublic List<ArticleVo> listArticlesPage(PageParams pageParams) {//  分页查询article数据库表Page<Article> page = new Page<>(pageParams.getPage(),pageParams.getPageSize());LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();//查询文章的参数 加上分类id,判断不为空 加上分类条件,SELECT * FROM article WHERE category_id = ?if (pageParams.getCategoryId() != null) {queryWrapper.eq(Article::getCategoryId,pageParams.getCategoryId());}//是否置顶排序,SELECT * FROM article ORDER BY weight DESC, create_date DESCqueryWrapper.orderByDesc(Article::getWeight,Article::getCreateDate);//SELECT * FROM article WHERE category_id = ? ORDER BY weight DESC, create_date DESCPage<Article> articlePage = articleMapper.selectPage(page,queryWrapper);List<Article> records = articlePage.getRecords();List<ArticleVo> articleVoList = copyList(records,true,false,true);return articleVoList;}
package com.cherriesovo.blog.vo.params;import lombok.Data;@Data
public class PageParams {private int page = 1;private int pageSize = 10;private Long categoryId;private Long tagId;
}

4. 标签文章列表

4.1 接口说明

接口url:/tags/detail/{id}

请求方式:GET

请求参数:

参数名称参数类型说明
id标签id路径参数

返回数据:

{"success": true, "code": 200, "msg": "success", "data": {"id": 5, "tagName": "springboot", "avatar": "/static/tag/java.png"}
}

4.2 Controller

TagsController:

 @GetMapping("detail/{id}")public Result findDetailById(@PathVariable("id") Long id){return tagService.findDetailById(id);}

4.3 Service

TagService:

Result findDetailById(Long id);

TagServiceImpl:

 @Overridepublic Result findDetailById(Long id) {//select * from tag where id = ?Tag tag = tagMapper.selectById(id);TagVo copy = copy(tag);return Result.success(copy);}

4.4 修改原有的查询文章接口

ArticleServiceImpl:

新增如下代码:

核心逻辑:

  1. 创建一个列表articleIdList用于存放某个标签对应的文章id;
  2. 通过tag_id在article_tag表中查询所有数据;
  3. 通过循环遍历操作将第二步查出来的数据中的article_id存放到articleIdList列表;
  4. SELECT *FROM article WHERE id IN articleIdList
	List<Long> articleIdList = new ArrayList<>();	//用于存储文章IDif (pageParams.getTagId() != null){/** 加入标签条件查询* article表中没有tag字段 一篇文章有多个标签* article_tag表中  article_id与tag_id是一对多的关系* */LambdaQueryWrapper<ArticleTag> articleTagLambdaQueryWrapper = new LambdaQueryWrapper<>();articleTagLambdaQueryWrapper.eq(ArticleTag::getTagId,pageParams.getTagId());//SELECT * FROM article_tag WHERE tag_id = ?List<ArticleTag> articleTags = articleTagMapper.selectList(articleTagLambdaQueryWrapper);for (ArticleTag articleTag : articleTags) {articleIdList.add(articleTag.getArticleId());}if (articleIdList.size() > 0){//SELECT *FROM article WHERE id IN (articleId1, articleId2, articleId3, ...)queryWrapper.in(Article::getId,articleIdList);}}
@Overridepublic List<ArticleVo> listArticlesPage(PageParams pageParams) {//  分页查询article数据库表Page<Article> page = new Page<>(pageParams.getPage(),pageParams.getPageSize());LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();//查询文章的参数 加上分类id,判断不为空 加上分类条件if (pageParams.getCategoryId() != null) {queryWrapper.eq(Article::getCategoryId,pageParams.getCategoryId());}List<Long> articleIdList = new ArrayList<>();if (pageParams.getTagId() != null){/** 加入标签条件查询* article表中没有tag字段 一篇文章有多个标签* article_tag表中  article_id与tag_id是一对多的关系* */LambdaQueryWrapper<ArticleTag> articleTagLambdaQueryWrapper = new LambdaQueryWrapper<>();articleTagLambdaQueryWrapper.eq(ArticleTag::getTagId,pageParams.getTagId());List<ArticleTag> articleTags = articleTagMapper.selectList(articleTagLambdaQueryWrapper);for (ArticleTag articleTag : articleTags) {articleIdList.add(articleTag.getArticleId());}if (articleIdList.size() > 0){queryWrapper.in(Article::getId,articleIdList);}}//是否置顶排序queryWrapper.orderByDesc(Article::getWeight,Article::getCreateDate);Page<Article> articlePage = articleMapper.selectPage(page,queryWrapper);List<Article> records = articlePage.getRecords();List<ArticleVo> articleVoList = copyList(records,true,false,true);return articleVoList;}

4.5 测试

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

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

相关文章

【C++函数】 scanf 与 printf 函数的标识符

标识符作用%d输入输出 int 类型%ld输入输出 long int 类型%lld输入输出 long long int 类型%hd输入输出 short 类型%i输入输出有符号十进制整数%u输入输出无符号十进制整数%lu输入输出无符号十进制长整数%llu输入输出无符号十进制超长整数%hu输入输出无符号十进制短整数%o输入输…

Python学习入门(2)——进阶功能

14. 迭代器和迭代协议 在Python中&#xff0c;迭代器是支持迭代操作的对象&#xff0c;即它们可以一次返回其成员中的一个。任何实现了 __iter__() 和 __next__() 方法的对象都是迭代器。 class Count:def __init__(self, low, high):self.current lowself.high highdef __i…

【Java】第十五届蓝桥杯JavaB组第一道填空题

&#xff03;【Java】第十五届蓝桥杯JavaB组第一道填空题 大家好 我是寸铁&#x1f44a; 总结了一篇【Java】第十五届蓝桥杯JavaB组第一道填空题文章 喜欢的小伙伴可以点点关注 &#x1f49d; Java B组 第一道填空题题解如下:

科研学习|科研软件——SPSS统计作图教程:多组折线图(≥3个变量)

一、问题与数据 研究者想研究45-65岁不同性别人群中静坐时长和血胆固醇水平的关系,分别招募50名男性和女性(gender)询问其每天静坐时长(time,分钟),并检测其血液中胆固醇水平(cholesterol, mmol/L),部分数据如图1。研究者该如何绘图展示这两者间的关系呢? 二、问题…

Traefik与传统的Edge Router有何不同?

在云原生时代&#xff0c;传统的网络架构和现代的解决方案之间存在明显的差异。特别是在处理网络流量和路由方面&#xff0c;传统的 Edge Router 与像 Traefik 这样的现代反向代理和负载均衡器相比&#xff0c;展现出许多不同的特点。本文将深入探讨 Traefik 与传统 Edge Route…

YOLO-World: Real-Time Open-Vocabulary Object Detection 简介+安装+运行+训练(持续更新)

前言 YOLO_WORLD太牛了&#xff01;&#xff01;众所周知&#xff0c;传统是视觉目标检测一旦训练好后&#xff0c;如果我们需要增加新的识别目标的话&#xff0c;必须得重新训练模型。在生产中如果经常要新增检测目标&#xff0c;对时效性影响很大&#xff0c;而且随着数据量…

.vue文件引入路径正确,但报错

问题描述 使用Vue挂载组件时&#xff0c;导入路径正确&#xff0c;但是一直提示 Already included file name ‘绝对路径/index.vue’ differs from file name ‘绝对路径/Index. vue’ only in casing. The file is in the program because: Imported via ‘./components/ind…

O2OA开发平台如何查看数据表结构?

在访问后端api地址&#xff0c;页面最下方有列示平台的各个服务&#xff0c;点击进入可查看具体的表内容 后端api地址&#xff1a; http://{hostIP}/x_program_center/jest/list.html 其中&#xff1a;{hostIP}为中心服务器所在域名或者IP地址 如下图&#xff1a;

25、链表-环形链表

思路&#xff1a; 这道题就是判断链表中是否有环&#xff0c;首先使用集合肯定可以快速地解决&#xff0c;比如通过一个set集合遍历&#xff0c;如果遍历过程中有节点在set中已经存在那么说明存在环。 第二种方式就是通过快慢指针方式寻找环。具体思路就是一个慢指针每次直走一…

Scala详解(2)

Scala 函数(Function) 概述 将一段逻辑进行封装便于进行重复使用&#xff0c;被封装的这段逻辑就是函数。在Scala中&#xff0c;必须通过def来定义函数 基本语法 def 函数名(参数列表) : 返回值类型 {函数体return 返回值 } 案例 // 案例&#xff1a;定义函数计算两个整数…

博客系统项目测试(selenium+Junit5)

在做完博客系统项目之后&#xff0c;需要对项目的功能、接口进行测试&#xff0c;利用测试的工具&#xff1a;selenium以及Java的单元测试工具Junit进行测试&#xff0c;下面式测试的思维导图&#xff0c;列出该项目需要测试的所有测试用例&#xff1a; 测试结果&#xff08;全…

Composer 安装与配置

Composer 是 PHP 领域中非常重要的一个工具&#xff0c;它作为 PHP 的依赖管理工具&#xff0c;帮助开发者定义、管理、安装项目所依赖的外部库。Composer 的出现极大地简化了 PHP 项目的构建和管理过程&#xff0c;使得开发者可以更加专注于代码的编写和功能的实现。 Compose…

当年明月在,曾照彩云归

肯定是非常辛苦和疲惫的 感谢一路走来帮助我的人 参考资料 小红书up主 哈嘿哈 孤独的演说家 白菜 run 今天你喝水了吗 HongReee 是个笨蛋呀 北航六人行 极限30天 青辰 懒哥 研究生啦(李珂欣) 林酱 QQ 雨梧桐🍁 Ctrl 林林 什么技术+答辩老师+代码什么作用+准备ppt+系统如何实…

Android12 user版本无法进入recovery问题

1.前言 之前Android9的时候公司自己写了一个简单的OTA在线升级&#xff0c;调用Recovery升级系统。后来Android12的时候想使用AB升级&#xff0c;发现我这套代码AB升级完成了之后&#xff0c;重启却无法切到B&#xff0c;所以造成升级一直是失败的。后来想着要不还是把AB关掉直…

linux下安装nacos2.2.0

1、获取下载地址并下载 1.1、打开nacos官网 1.2、找到对应版本&#xff0c;点进去 ## 1.3、复制地址 1.4下载 # 进入要安装的目录&#xff0c;cd /usr/local/src # 执行wget https://github.com/alibaba/nacos/releases/download/2.2.0/nacos-server-2.2.0.tar.gz2、 安装…

springboot数字化智慧城市管理系统源码

目录 ​系统开发环境 系统功能模块 系统特点 1、智慧城管移动端 2、案件受理 3、AI视频智识别分析 系统应用价值 1、提升案件办理效率 2、提升监管效能 3、提升行政执法水平 4、推进行政执法创新 智慧城管综合执法办案系统功能 现场移动执法 一般程序案件的网上办…

Modern C++:提升开发效率的语法糖详解与实例

引言 Modern C&#xff0c;特指自C11以来的一系列标准更新&#xff0c;引入了大量旨在增强语言表达力、提高代码清晰度与开发效率的新特性。其中&#xff0c;被称为“语法糖”的便捷语法构造尤为引人注目。这些语法糖不仅简化了程序员的日常编码工作&#xff0c;减少了出错几率…

D00178-变压器设备漏油的检测数据集338张含VOC标签

数据集一部分来自真实场景&#xff0c;由于真实场景下样本较少&#xff0c;共338张&#xff0c;采用VOC标注格式 完整链接见文末 完整链接&#xff1a; D00178-变压器设备漏油的检测数据集338张含VOC标签

今日arXiv最热大模型论文:清华大学发布,ChatGML又添新功能,集成“自我批评”,提升数学能力

引言&#xff1a;数学问题解决在大语言模型中的挑战 在当今的人工智能领域&#xff0c;大语言模型&#xff08;Large Language Models&#xff0c;LLMs&#xff09;已经在理解和生成人类语言方面取得了显著的进展。这些模型在文本摘要、问答、角色扮演对话等多种语言任务上展现…

现在租一个服务器多少一个月啊?

现在租一个服务器多少一个月&#xff1f;优惠价格低至3.8元1个月&#xff0c;租用一个月云服务器收费价格表&#xff1a;阿里云和腾讯云2核2G3M服务器优惠价格61元一年&#xff0c;折合一个月5元&#xff0c;京东云轻量云主机5.8元一个月&#xff0c;华为云服务器优惠价格3.8元…