首页 > 其他分享 >个人博客项目笔记_08

个人博客项目笔记_08

时间:2024-04-12 11:59:15浏览次数:26  
标签:queryWrapper 笔记 08 博客 public tag Result import id

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

请求参数:

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

返回数据:

{
    "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 {
    @Autowired
    private QiniuUtils qiniuUtils;

    @PostMapping
    public Result upload(@RequestParam("image") MultipartFile file){
        //原始文件名称 比如:1.png
        String 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或者自己的url
    public 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 方法生成上传凭证 upToken
            Response response = uploadManager.put(uploadBytes, fileName, upToken);//执行文件上传
            //解析上传成功的结果,将上传结果的 JSON 字符串解析为 DefaultPutRet 类对象 putRet
            DefaultPutRet 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:

 @Override
    public 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));
    }

 @Override
    public 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:

	@Override
    public 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));
    }

    @Override
    public Result findAllDetail() {
        LambdaQueryWrapper<Tag> queryWrapper = new LambdaQueryWrapper<>();
        //select * from tag
        List<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:

@Override
    public 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());
​ }

@Override
    public 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 DESC
        queryWrapper.orderByDesc(Article::getWeight,Article::getCreateDate);
        //SELECT * FROM article WHERE category_id = ? ORDER BY weight DESC, create_date DESC
        Page<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:

 @Override
    public 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<>();	//用于存储文章ID
    if (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);
        }
    }
   @Override
    public 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 测试

标签:queryWrapper,笔记,08,博客,public,tag,Result,import,id
From: https://www.cnblogs.com/zyj3955/p/18130859

相关文章

  • onJava8学习笔记
    onJava8:ThinkingInJavasequel第一章:对象的概念※,复用组合(UML实心三角形)和聚合(UML空心三角形)都属于关联关系的一种,只是额外具有整体-部分的意义。至于是聚合还是组合,需要根据实际的业务需求来判断。可能相同超类和子类,在不同的业务场景,关联关系会发生变化。只看代码是无法......
  • server2008安装.netcore api
    一、先写个简单点的.netcoreapi1publicclassProgram2{3publicstaticvoidMain(string[]args)4{5varbuilder=WebApplication.CreateBuilder(args);67//Addservicestothecontainer.89......
  • 狂神说Java Web学习笔记_Session
    原理图服务器会给每一个用户(浏览器)创建一个session对象一个session独占一个浏览器,主要浏览器没有关,这个session就存在登录之后,整个网站都可以访问常用场景保存一个用户的登录信息在整个网站中经常会使用到的数据常用的session方法//得到SessionHttpSessionsession=re......
  • shell practice 08
    #!/bin/bash#author:ChiWeiming#version:v1#date:2024-04-12<<COMMANT输入一个数字,然后运行对应的一个命令。显示命令如下:*cmdmeau**1-date2-ls3-who4-pwd当输入1时,执行date命令,输入2时执行ls命令,依此类推COMMANTecho"*cmdmeau**1-date2-ls3-......
  • 狂神说Java Web学习笔记_Cookie
    会话用户打开一个浏览器,点击了很多链接,访问了很多web资源,关闭浏览器之后,这个过程可以称之为一次会话。有状态会话一个同学来过教室,大家看到了,下次再来教室的时候,我们会知道这个同学曾经来过,这个被称为有状态会话。一个网站如何证明你访问过?服务端给客户端一个信件,客户端下次......
  • 1st Universal Cup 做题笔记
    Stage1:Shenyanghttps://qoj.ac/contest/1096A只需要考虑每个pair的贡献即可,而相交的pair数量是线性的,因此可以暴力搞,剩下的不相交的pair拿前缀和做就行了,复杂度\(\mathcalO(n\logn)\)。cornercase是当一方的区间全部退化的时候,需要重新计算一下出现的概率。BC......
  • [学习笔记] LCA - 图论
    [NOIP2013提高组]货车运输最大生成树+LCA+倍增好家伙,这道题我写了一个晚上,调了两个晚上,对于这道题我颇有感触。但这道题确实好,实实在在的蓝题,让我发现了许多关于LCA的问题。首先,这个题给的是一个无向图,并不是个树,为了减少运算量,我们可以把它变成一个树。运用Kruskal算法生......
  • 树链剖分 学习笔记
    随便写一点。1.原理定义重儿子为子树内子树大小最大的任一个点,重边为重儿子向其父亲连的边,其余为轻边。根据定义,轻边的父亲的子树大小一定不小于这个点的子树大小的二倍。又可以证出重边数量是\(O(\logn)\)的。因此可以用线段树维护这个东西。2.应用2.1dsu2.2lca考......
  • 点分治学习笔记
    前置知识:树的重心对于一颗无根树上的每一个点,计算其所有子树中最大的子节点数,这个值最小的点就是树的重心1.定义点分治,又叫树分治,点分治是一种在树上进行路径静态统计的算法,所谓树上的静态统计,并不是像树剖一样维护路径最值,路径之和一类的统计,点分治的本质其实是将一棵树拆分......
  • 小熊派BearPi-HM_nano开发笔记及避坑
    小熊派BearPi-HM_nano开发笔记及避坑前排提示:直接使用官方提供的Ubuntu18.04OVF,自己配有诸多问题,PPT未给出详细方案。即使是用虚拟机OVF,也有不少坑,现记录如下:基本配置问题1:Certificateverificationfailed:ThecertificateisNOTtrusted执行sudoaptupdate时提示“Cert......