Springboot操作Redis
Mac下安装Redis
一行命令即可安装 brew install redis
安装成功后即可通过redis-cli
进行命令行式的链接交互
习惯用可视化软件的也可以用一些免费开源的工具,如AnotherRedisDesktopManager
下载地址:github.com/qishibo/Ano…
接着在pom.xml
中添加如下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
同时对redis
的链接配置进行设置,这里我的测试环境没有密码所以为空
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0
做到这里,其实已经可以通过自动装配依赖注入使用redis
会话进行操作了,编写一个Controller
进行测试验证
package cn.mgl.rds.demos.web;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("redis")
public class RedisController {
private final RedisTemplate redisTemplate;
public RedisController(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
@GetMapping("setSome")
public Object setSome(String key,String value){
redisTemplate.opsForValue().set(key,value);
return "设置成功";
}
@GetMapping("getSome")
public Object getSome(String key) {
Object o = redisTemplate.opsForValue().get(key);
return "value is "+ o;
}
}
RedisTemplate
是容器里已经初始化好的对象,可以通过它来操控,其中会提供很多opsForXXX
的方法,其中ops
实际上就是Operations
的意思,这里用opsForValue
去操作字符串相关数据
此时其实已经可以开始测试了,但是由于默认自动装配的redis
对编码的配置上并不友好,所以可能存在一些编码格式导致读写不符合预期的问题,编写一个Redis配置类,做一些json格式化的方案
package cn.mgl.rds.configuration;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
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.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 配置 ObjectMapper 的可见性,以便其可以访问所有成员变量(包括私有变量),即使这些变量没有公共的 getter 或 setter 方法
// PropertyAccessor.ALL:表示所有类型的成员(字段、getter、setter、creator)。
// JsonAutoDetect.Visibility.ANY:表示所有的成员都应该是可见的。
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
// 启用默认类型信息,以便在序列化和反序列化时包含对象的类型信息。这样在反序列化时,Jackson 可以正确地重建对象的类型
// LaissezFaireSubTypeValidator.instance:这是一个类型验证器,允许所有子类型。它在 Jackson 2.10 之后被引入,作为 @JsonTypeInfo 的一个安全性改进
// ObjectMapper.DefaultTyping.NON_FINAL:仅对非最终类启用类型信息,也就是说,对于不能被继承的最终类,不会启用类型信息
// JsonTypeInfo.As.PROPERTY:将类型信息作为属性包含在 JSON 数据中
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 设置key的序列化方式
template.setKeySerializer(stringRedisSerializer);
// 设置Hash key的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// 设置value的序列化方式
template.setValueSerializer(jackson2JsonRedisSerializer);
// 设置hash value的序列化方式
template.setHashValueSerializer(jackson2JsonRedisSerializer);
// spring会调用这个方法来完成RedisTemplate的初始化过程,执行这个方法确保配置生效
template.afterPropertiesSet();
return template;
}
}
这里通过自己生成一个Bean
来覆盖默认配置,各种配置的说明都在代码注释中了,核心就是用StringRedisSerializer
对各种键进行序列化,用Jackson2JsonRedisSerializer
来对各种值进行序列化,并且配置了ObjectMapper
来支持json
的序列化和反序列化
最后,再编写一个工具类来简化操作,这样就不需要每次都操作RedisTemplate
,只举例读取键和设置健值对
package cn.mgl.rds.util;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Redis工具类
*/
@Component
public class RedisUtil {
private final RedisTemplate<String, Object> redisTemplate;
public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 根据Key获取值
*
* @param key 给定键
* @return key对应值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 将key,value放入缓存
*
* @param key 键
* @param value 值
*/
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 将key,value放入缓存
*
* @param key 键
* @param value 值
*/
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 将key,value放入缓存
*
* @param key 键
* @param value 值
* @param time 过期时间,-1则表示不过期
*/
public void set(String key, String value, long time) {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
redisTemplate.opsForValue().set(key, value);
}
}
}
现在开始进行测试,先调用一次设置相关的接口,这里返回1说明设置成功了
接着再调用根据键获取数据的接口,可以看到也是成功获取到了刚才设置的10022
开启链接池提高性能
springboot2.x
默认使用Lettuce
客户端来链接Redis
服务,默认不使用链接池,只有在配置了redis.lettuce.pool
属性后才可以使用链接池,同时要引入依赖commons-pool2
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
接着添加redis
链接池相关配置,为了方便改成了yaml
server:
port: 8080
spring:
redis:
host: 127.0.0.1
port: 6379
password:
database: 0
lettuce:
pool:
max-active: 20
max-idle: 10
min-idle: 5
max-wait: 5000ms
max-active
:限制同时从连接池中获取的最大连接数,超过这个数值后,新请求会被阻塞,直到有连接被归还到池中max-idel
:控制连接池中空闲连接的最大数量,如果空闲连接数超过这个值,多余的空闲连接将会被销毁min-idle
:确保连接池中最少有多少个空闲连接。这些空闲连接会在后台不断补充,确保始终有一定数量的空闲连接可用max-wait
:在请求连接时,如果没有可用连接,最大等待时间是 5000 毫秒(即 5 秒)。如果在这个时间内还是无法获取连接,就会抛出异常
还需要解决下redis
一些默认配置导致无法用其他网络连接的问题
如何找到mac下通过brew安装的redis的配置文件所在
先通过brew list redis
找到redis的目录
接着查看homebrew.mxcl.redis.plist
这个文件中ProgramArguments
下的配置,图中红框就是配置文件地址所在
- 通过任意方式进行修改文件,把
bind 127.0.0.1 ::1
这一行注释,表示接受外来地址 - 再把
protected-mode yes
改成no
(默认是yes
),表示取消保护模式
重启下服务brew services restart redis
最后给出一个利用redis
工具类的使用
package cn.mgl.rds.demos.web;
import cn.mgl.rds.util.RedisUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("redis")
public class RedisController {
private final RedisUtil redisUtil;
public RedisController(RedisUtil redisUtil) {
this.redisUtil = redisUtil;
}
@GetMapping("setSome")
public Object setSome(String key, String value) {
redisUtil.set(key, value);
return "设置成功";
}
@GetMapping("getSome")
public Object getSome(String key, HttpServletRequest request) {
Object o = redisUtil.get(key);
return "设置成功,值为:" + o;
}
}
完:)
转载自:https://juejin.cn/post/7384633860519051316