项目实战第十九记
- 写在前面
- 1. redis安装(windows安装)
- 1.1 获取软件链接地址:
- 1.2 启动redis
- 1.3 测试是否启动成功
- 1.4 通过 Another Redis DeskTop软件可视化查看redis
- 2. SpringBoot集成redis
- 2.1 引入依赖
- 2.2 注入RedisTemplate
- 2.3 使用redis
- 2.4 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 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
修改application.yml文件
redis:
port: 6379
host: 127.0.0.1
# password: XXX
# mode: XXX
# database: xxx
2.2 注入RedisTemplate
@Autowired
private RedisTemplate redisTemplate;
枚举类设置redis的键:
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
// 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更新
// 刷新缓存(遇到增删改,更新缓存)
public void flushRedis(String key){
redisTemplate.delete(key);
}
完整的FileController代码:
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,感谢!!不懂的可以在评论区评论,有空会及时回复。
文章会一直更新