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 ,感谢!!不懂的可以在评论区评论 ,有空会及时回复。
文章会一直更新

相关推荐
卓卓没头发39 分钟前
掌握Vue插槽:创建灵活且可复用的组件
前端·javascript·vue.js
用户4099322502122 小时前
Nuxt框架中内置组件详解及使用指南(三)
前端·vue.js·nuxt.js
java6666688882 小时前
如何在Spring Boot中实现实时通知
java·spring boot·后端
虫小宝2 小时前
Spring Boot与Jenkins的集成
spring boot·后端·jenkins
java6666688883 小时前
在Spring Boot中集成分布式日志收集方案
spring boot·分布式·jenkins
java6666688883 小时前
深入理解Spring Boot中的配置加载顺序
java·spring boot·后端
AllenIverrui3 小时前
MyBatisPlus的使用
spring boot·spring·java-ee·mybatis
冯宝宝^3 小时前
图书管理系统
服务器·数据库·vue.js·spring boot·后端
五月阳光暖洋洋3 小时前
SpringBoot2.2.6使用spring-boot-validation读取不到自定义配置文件中的属性
java·开发语言·spring boot
java6666688884 小时前
深入理解Spring Boot中的容器与依赖注入
java·spring boot·后端