springboot + Vue前后端项目(第十九记)

项目实战第十九记

  • 写在前面
  • [1. redis安装(windows安装)](#1. redis安装(windows安装))
    • [1.1 获取软件链接地址:](#1.1 获取软件链接地址:)
    • [1.2 启动redis](#1.2 启动redis)
    • [1.3 测试是否启动成功](#1.3 测试是否启动成功)
    • [1.4 通过 Another Redis DeskTop软件可视化查看redis](#1.4 通过 Another Redis DeskTop软件可视化查看redis)
  • [2. SpringBoot集成redis](#2. SpringBoot集成redis)
    • [2.1 引入依赖](#2.1 引入依赖)
    • [2.2 注入RedisTemplate](#2.2 注入RedisTemplate)
    • [2.3 使用redis](#2.3 使用redis)
    • [2.4 redis更新](#2.4 redis更新)
    • [2.5 redis使用前后对比](#2.5 redis使用前后对比)
  • 总结
  • 写在最后

写在前面

本篇主要讲解SpringBoot集成redis在系统中的简单应用

1. redis安装(windows安装)

1.1 获取软件链接地址:

链接:https://pan.baidu.com/s/1b-NFQzAcdujjy2WugWU6fQ 
提取码:6666

1.2 启动redis

1.3 测试是否启动成功

输入ping,显示pong;说明redis启动成功

1.4 通过 Another Redis DeskTop软件可视化查看redis

软件链接地址

链接:https://pan.baidu.com/s/1A_-8h-MHfcWKFh6UbWU8bw 
提取码:6666

如下图所示:

2. SpringBoot集成redis

2.1 引入依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

修改application.yml文件

yml 复制代码
  redis:
    port: 6379
    host: 127.0.0.1
#    password: XXX
#    mode: XXX
#    database: xxx

2.2 注入RedisTemplate

java 复制代码
@Autowired
private RedisTemplate redisTemplate;

枚举类设置redis的键:

java 复制代码
package com.ppj.constants;

public interface Constants {

    String CODE_200 = "200"; //成功
    String CODE_401 = "401";  // 权限不足
    String CODE_400 = "400";  // 参数错误
    String CODE_500 = "500"; // 系统错误
    String CODE_600 = "600"; // 其他业务异常

    String CODE_700 = "700";  //注册失败

    // redis
    String FILES_KEY = "FILES_FRONT_ALL";
}

2.3 使用redis

java 复制代码
// JSONUtil是hutool工具包下面的
//1, 从redis中获取数据
        String jsonStr = JSONUtil.toJsonStr(redisTemplate.opsForValue().get(Constants.FILES_KEY));
        List<Files> filesList;
        //2, 判断取出的数据是否为空
        if(StrUtil.isBlank(jsonStr)){
            filesList = fileService.list();
            // 缓存到redis中
            redisTemplate.opsForValue().set(Constants.FILES_KEY,JSONUtil.toJsonStr(filesList));
        }else{
            // 从redis缓存中获取数据
           filesList = JSONUtil.toList(jsonStr, Files.class);
        }
        return Result.success(filesList);

2.4 redis更新

java 复制代码
// 刷新缓存(遇到增删改,更新缓存)
public void flushRedis(String key){
   redisTemplate.delete(key);
}

完整的FileController代码:

java 复制代码
package com.ppj.controller;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ppj.constants.Constants;
import com.ppj.entity.Files;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ppj.common.Result;

import com.ppj.service.IFileService;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author ppj
 * @since 2024-05-21
 */
@RestController
@RequestMapping("/file")
public class FileController {

    @Resource
    private IFileService fileService;

    @Value("${files.upload.path}")
    private String fileUploadPath;

    @Autowired
    private RedisTemplate redisTemplate;

    // 新增或者更新
    @PostMapping
    public Result save(@RequestBody Files file) {
        flushRedis(Constants.FILES_KEY);
        fileService.saveOrUpdate(file);
        return Result.success();
    }

    @DeleteMapping("/{fileIds}")
    public Result delete(@PathVariable Integer[] fileIds) {
        flushRedis(Constants.FILES_KEY);
        fileService.removeByIds(Arrays.asList(fileIds));
        return Result.success();
    }

    @GetMapping
    public Result findAll() {
        // 1, 从redis中获取数据
        String jsonStr = JSONUtil.toJsonStr(redisTemplate.opsForValue().get(Constants.FILES_KEY));
        List<Files> filesList;
        // 2,判断取出的数据是否为空
        if(StrUtil.isBlank(jsonStr)){
            filesList = fileService.list();
            // 缓存到redis中
            redisTemplate.opsForValue().set(Constants.FILES_KEY,JSONUtil.toJsonStr(filesList));
        }else {
            // 从redis缓存中获取数据
            filesList = JSONUtil.toList(jsonStr, Files.class);
        }
        return Result.success(filesList);
    }


    @GetMapping("/page")
    public Result findPage(@RequestParam Integer pageNum,
                                @RequestParam Integer pageSize,
                           @RequestParam String name) {
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name",name);
//        queryWrapper.orderByDesc("id");
        return Result.success(fileService.page(new Page<>(pageNum, pageSize), queryWrapper));
    }


    /**
     * 文件上传接口
     * @param file 前端传递过来的文件
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String type = FileUtil.extName(originalFilename);
        long size = file.getSize();

        // 定义一个文件唯一的标识码
        String uuid = IdUtil.fastSimpleUUID();
        String fileUUID = uuid + StrUtil.DOT + type;

        File uploadFile = new File(fileUploadPath + fileUUID);
        // 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
        File parentFile = uploadFile.getParentFile();
        if(!parentFile.exists()) {
            parentFile.mkdirs();
        }

        String url;
        // 获取文件的md5
        String md5 = SecureUtil.md5(file.getInputStream());
        // 从数据库查询是否存在相同的记录
        Files dbFiles = getFileByMd5(md5);
        if (dbFiles != null) { // 文件已存在,直接返回数据库里的url
            url = dbFiles.getUrl();
        } else {  // 文件不存在才生成url,保存数据至数据库
            // 上传文件到磁盘
            file.transferTo(uploadFile);
            // 数据库若不存在重复文件,则不删除刚才上传的文件
            url = "http://localhost:9000/file/" + fileUUID;
            // 存储数据库
            Files saveFile = new Files();
            saveFile.setName(originalFilename);
            saveFile.setType(type);
            saveFile.setSize(size/1024);
            saveFile.setUrl(url);
            saveFile.setMd5(md5);
            fileService.saveOrUpdate(saveFile);
        }
        return url;
    }

    /**
     * 通过文件的md5查询文件
     * @param md5
     * @return
     */
    private Files getFileByMd5(String md5) {
        // 查询文件的md5是否存在
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5", md5);
        Files one = fileService.getOne(queryWrapper);
        return one != null ? one : null;
    }

    /**
     * 文件下载接口   http://localhost:9090/file/{fileUUID}
     * @param fileUUID
     * @param response
     * @throws IOException
     */
    @GetMapping("/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        // 根据文件的唯一标识码获取文件
        File uploadFile = new File(fileUploadPath + fileUUID);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        // 读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }

    @PostMapping("/update")
    public Result changeEnable(@RequestBody Files files){
        flushRedis(Constants.FILES_KEY);
        return fileService.saveOrUpdate(files)?Result.success():Result.error();
    }

    // 刷新缓存(遇到增删改,更新缓存)
    public void flushRedis(String key){
        redisTemplate.delete(key);
    }

}

2.5 redis使用前后对比

redis未存储数据前,每刷新一次页面,就会重新去数据库请求一遍数据,后台会有日志打印信息,如下图所示:

当数据存储在redis后,刷新页面不再去请求数据库,而是直接从redis中取数据,从而减轻了数据库的访问压力。如下图所示,再次刷新,后台没有日志记录。

总结

  • 为什么使用redis,因为用它可以减轻数据库访问压力

写在最后

如果此文对您有所帮助,请帅戈靓女们 务必不要吝啬你们的Zan ,感谢!!不懂的可以在评论区评论 ,有空会及时回复。
文章会一直更新

相关推荐
木子02041 小时前
前端VUE项目启动方式
前端·javascript·vue.js
捂月1 小时前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
运维-大白同学2 小时前
将django+vue项目发布部署到服务器
服务器·vue.js·django
星星会笑滴3 小时前
vue+node+Express+xlsx+emements-plus实现导入excel,并且将数据保存到数据库
vue.js·excel·express
FIN技术铺3 小时前
Spring Boot框架Starter组件整理
java·spring boot·后端
Backstroke fish3 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
临枫5413 小时前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
RAY_CHEN.3 小时前
vue3 pinia 中actions修改状态不生效
vue.js·typescript·npm
酷酷的威朗普3 小时前
医院绩效考核系统
javascript·css·vue.js·typescript·node.js·echarts·html5
_Legend_King3 小时前
vue3 + elementPlus 日期时间选择器禁用未来及过去时间
javascript·vue.js·elementui