SpringBoot Redis 缓存
2021-05-15 本文已影响0人
小虎哥的技术博客
一、前言
Redis是内存数据库,什么是内存数据库,内存数据库是相对于硬盘数据库的。您的电脑配置是内存16G,硬盘500G,Redis的数据就是放在16G内存中,Mysql数据就放在500G硬盘中。
内存读写速度快,所以Redis数据库快,那它可以做缓存和一些访问率高的数据存储。
因为是内存数据库,所以Redis存储容量小,而且断电了数据会丢失。
所以Redis不要存储数据量大的数据,对于断电数据丢失,redis有两种持久化策略(记录命令和定时刷盘),这些后续再说。
废话不多话,SpringBoot集成Redis,直接上代码。
二、目录结构和配置
2.1 目录结构
QQ截图20210515114031.png2.2 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.llh</groupId>
<artifactId>spring-boot-redis</artifactId>
<version>1.0.0</version>
<name>spring-boot-redis</name>
<description>spring-boot-redis project description</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
- 就是加了这个
spring-boot-starter-data-redis
依赖
2.3 application.properties
# 应用名称
spring.application.name=spring-boot-redis
server.port=8888
# redis 地址
spring.redis.host=localhost
spring.redis.port=6379
- 主要就是redis的地址 端口配置
三、代码
RedisConfiguration
类
package com.llh.springbootredis.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author llh
*/
@Configuration
public class RedisConfiguration {
private final RedisConnectionFactory redisConnectionFactory;
@Autowired
public RedisConfiguration(RedisConnectionFactory redisConnectionFactory) {
this.redisConnectionFactory = redisConnectionFactory;
}
@Bean()
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
@Bean
public StringRedisTemplate stringRedisTemplate() {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
return stringRedisTemplate;
}
}
- 这里主要就是注入
redisTemplate
和stringRedisTemplate
对象 -
redisTemplate
是可以操作对象的,里面配置了对象的序列化方式 -
stringRedisTemplate
只能操作字符串
UserInfo
类
package com.llh.springbootredis.bean;
import java.io.Serializable;
/**
* @author llh
*/
public class UserInfo implements Serializable {
private static final long serialVersionUID = -4514567603228180464L;
private Long id;
private String username;
private String password;
public UserInfo(Long id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "UserInfo{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
- 实体类一定要实现
Serializable
接口,因为对象要序列化保存
TestService
类
package com.llh.springbootredis.service;
import com.llh.springbootredis.bean.UserInfo;
/**
* @author llh
*/
public interface TestService {
String test0(Long id);
UserInfo test1(Long id);
}
TestServiceImpl
类
package com.llh.springbootredis.service.impl;
import com.llh.springbootredis.bean.UserInfo;
import com.llh.springbootredis.service.TestService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.UUID;
/**
* @author llh
*/
@Service
public class TestServiceImpl implements TestService {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override
public String test0(Long id) {
// 模拟延迟操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("产生一个新字符串");
UUID uuid = UUID.randomUUID();
String str = uuid.toString();
String cacheKey = "str:" + id;
System.out.println("redis缓存此字符串 " + cacheKey + " ===> " + str);
stringRedisTemplate.opsForValue().set(cacheKey, str);
return str;
}
@Override
public UserInfo test1(Long id) {
// 模拟延迟操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("产生一个新对象");
UserInfo userInfo = new UserInfo(id, "admin", "123456");
String cacheKey = "user:" + id;
System.out.println("redis缓存此对象 " + cacheKey + " ===> " + userInfo);
redisTemplate.opsForValue().set(cacheKey, userInfo);
return userInfo;
}
}
-
stringRedisTemplate.opsForValue().set(cacheKey, str);
主要就是这一句,将数据保存到Redis数据库。
TestController
类
package com.llh.springbootredis.controller;
import com.llh.springbootredis.bean.UserInfo;
import com.llh.springbootredis.service.TestService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author llh
*/
@RestController
public class TestController {
@Resource
private TestService testService;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@GetMapping("test0/{id}")
public String test0(@PathVariable Long id) {
// 查询缓存
String cacheKey = "str:" + id;
String cacheVal = stringRedisTemplate.opsForValue().get(cacheKey);
if (cacheVal != null) {
System.out.println("redis缓存中直接返回字符串");
return cacheVal;
}
return testService.test0(id);
}
@GetMapping("test1/{id}")
public UserInfo test1(@PathVariable Long id) {
// 查询缓存
String cacheKey = "user:" + id;
UserInfo cacheVal = (UserInfo) redisTemplate.opsForValue().get(cacheKey);
if (cacheVal != null) {
System.out.println("redis缓存中直接返回对象");
return cacheVal;
}
return testService.test1(id);
}
}
-
stringRedisTemplate.opsForValue().get(cacheKey)
获取缓存的数据。 - 缓存的Key都是字符串
- 缓存的Value,
test0
接口是字符串test1
接口是对象 - 通过id来缓存的,为了区分数据类型,字符串Key的前缀是
str:
,对象Key的前缀是user:
四、测试
- localhost:8888/test0/1
- localhost:8888/test0/2
- localhost:8888/test1/1
- localhost:8888/test1/2
- 打印的日志可以看到相同的请求第一次是创建新的对象,第二次直接从Redis中获取,从Redis中获取速度是非常快的。
- Redis数据库中也有了4条数据。
五、总结
Redis应该是目前使用最多的内存数据库了,除了做缓存之外,根据Redis的数据类型特性还可以做很多好玩的东西。比如分布式锁,点赞评论等。我们这里只用到了最简单的Key->String类型。它还有Key->List,Key->Map,Key->Set,Key->ZSet等。
GitHub源码地址:https://github.com/tigerleeli/xiaohuge-blog/tree/master/spring-boot-redis