SpringBoot整合Redis
首先,需要安装windows版的Redis
可以参考这篇文章: https://blog.csdn.net/weixin_41381863/article/details/88231397
然后在pom.xml中引入redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.4.3</version>
</dependency>
配置application.properties文件(虽然yml方式写起来会少很多,但是我觉得properties版本看起来整齐一点)
#Reids
#数据库索引,默认0
spring.redis.database=0
#Redis服务器地址
spring.redis.host=127.0.0.1
#端口
spring.redis.port=6379
#登录密码,默认为空
spring.redis.password=
#连接池最大连接数(负值表示无限制)
spring.redis.jedis.pool.max-active=8
#连接池最大阻塞等待时间(负值表示无限制)
spring.redis.jedis.pool.max-wait=-1ms
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
#连接超时时间(毫秒)
sping.redis.timeout=5000
然后编写Redis配置类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Autowired
private RedisTemplate redisTemplate;
/**
* 解决redis插入中文乱码
* @return
*/
@Bean
public RedisTemplate redisTemplateInit(){
//设置序列化key的实例化对象
redisTemplate.setKeySerializer(new StringRedisSerializer());
//设置实例化value的实例化对象
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}
然后下面是我自己写的一个工具类(部分操作Redis的方法),我有点强迫症,有的方法名称和jedis的一样
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Redis工具类
*/
@Component
public class RedisUtil {
Logger LOGGER = LoggerFactory.getLogger(RedisUtil.class);
@Resource
private RedisTemplate<String,Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String,Object> redisTemplate){
this.redisTemplate = redisTemplate;
}
/**
* 设置key的失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time){
try{
if(time > 0){
redisTemplate.expire(key,time, TimeUnit.SECONDS);
}
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 获取key的失效时间
* @param key 键
* @return 时间(秒),如果返回0,则表示永久有效
*/
public long getExpire(String key){
return redisTemplate.getExpire(key,TimeUnit.SECONDS);
}
/**
* 判断key是否存在
* @param key
* @return true存在,否则不存在
*/
public boolean hasKey(String key){
try{
return redisTemplate.hasKey(key);
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 删除key
* @param key 一个或多个
*/
public void del(String ...key){
if(key != null && key.length > 0){
if(key.length == 1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
/*
字符串类型
*/
/**
* 根据键获取值
* @param key
* @return
*/
public Object get(String key){
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 设置新的键值对
* @param key
* @param value
* @return
*/
public boolean set(String key,Object value){
try{
redisTemplate.opsForValue().set(key, value);
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 新增带失效时间的键值对
* @param key
* @param value
* @param time time要大于0,否则就为无期限
* @return
*/
public boolean setnx(String key,Object value,long time){
try{
redisTemplate.opsForValue().set(key, value, time,TimeUnit.SECONDS);
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 将key指向的value的值加delta
* @param key
* @param delta
* @return
*/
public long incr(String key,long delta){
if(delta < 0){
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 将key指向的value的值减delta
* @param key
* @param delta
* @return
*/
public long decr(String key,long delta){
if(delta < 0){
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
/*
Hash
*/
/**
* 根据key和key的字段名,获取字段值
* @param key
* @param field
* @return
*/
public Object hGet(String key,String field){
return redisTemplate.opsForHash().get(key,field);
}
/**
* 获取key的所有键值对
* @param key
* @return
*/
public Map<Object,Object> hGetAll(String key){
return redisTemplate.opsForHash().entries(key);
}
/**
* 新增多个键值对
* @param key
* @param map
* @return
*/
public boolean hmSet(String key,Map<String,Object> map){
try{
redisTemplate.opsForHash().putAll(key,map);
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 新增多个键值对并设置失效时间,时间必须大于0,否则为永久有效
* @param key
* @param map
* @param time 秒
* @return
*/
public boolean hmSetnx(String key,Map<String,Object> map,long time){
try{
redisTemplate.opsForHash().putAll(key,map);
if(time > 0 ){
expire(key,time);
}
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 设置单个键值对
* @param key
* @param field
* @param value
* @return
*/
public boolean hSet(String key,String field,Object value){
try{
redisTemplate.opsForHash().put(key,field,value);
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 判断这个hash表中是否有这个字段
* @param key
* @param field
* @return
*/
public boolean hHasKey(String key,String field){
return redisTemplate.opsForHash().hasKey(key,field);
}
/*
Set
*/
/**
* 根据key获取set中所有的值
* @param key
* @return
*/
public Set<Object> sGet(String key){
try{
return redisTemplate.opsForSet().members(key);
}catch (Exception e){
LOGGER.info(e.getMessage());
return null;
}
}
/**
* 判断value在key中是否存在
* @param key
* @param value
* @return
*/
public boolean sHasKey(String key,Object value){
try{
redisTemplate.opsForSet().isMember(key, value);
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 向名为key的set集合中新增values值
* @param key
* @param values 一个或多个
* @return 成功个数
*/
public long sAdd(String key,Object ...values){
try{
return redisTemplate.opsForSet().add(key,values);
}catch (Exception e){
LOGGER.info(e.getMessage());
return 0;
}
}
/**
* 获取set集合key的长度
* @param key
* @return
*/
public long sCard(String key){
try{
return redisTemplate.opsForSet().size(key);
}catch (Exception e){
LOGGER.info(e.getMessage());
return 0;
}
}
/**
* 移除集合中指定的一个或多个值
* @param key
* @param values
* @return
*/
public long sRem(String key,Object ...values){
try{
return redisTemplate.opsForSet().remove(key, values);
}catch (Exception e){
LOGGER.info(e.getMessage());
return 0;
}
}
/*
List
*/
/**
* 获取一个list集合的所有值
* @param key 集合名称
* @param start 开始索引
* @param end 结束索引,当start=0,end=-1时,表示获取所有元素(包左包右)
* @return
*/
public List<Object> lRange(String key,long start,long end){
try{
return redisTemplate.opsForList().range(key, start, end);
}catch (Exception e){
LOGGER.info(e.getMessage());
return null;
}
}
/**
* 获取list的长度
* @param key
* @return
*/
public long lLen(String key){
try{
return redisTemplate.opsForList().size(key);
}catch (Exception e){
LOGGER.info(e.getMessage());
return 0;
}
}
/**
* 获取list集合中指定索引的元素,数据结构和栈一样
* @param key
* @param index 当index>=0时,0表示表头,1是第二个元素;当index<0时,-1表示表头
* @return
*/
public Object lIndex(String key,long index){
try{
return redisTemplate.opsForList().index(key, index);
}catch (Exception e){
LOGGER.info(e.getMessage());
return null;
}
}
/**
* 向list集合中,插入单个元素(压栈)
* @param key
* @param value
* @return
*/
public boolean lPush(String key,Object value){
try{
redisTemplate.opsForList().rightPush(key, value);
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 向list集合中,插入多个元素(压栈)
* @param key
* @param list
* @return
*/
public boolean lPushAll(String key,List<Object> list){
try{
redisTemplate.opsForList().rightPushAll(key, list);
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 根据索引修改list中的某个值
* @param key
* @param index
* @param value
* @return
*/
public boolean lUpdateIndex(String key,long index,Object value){
try{
redisTemplate.opsForList().set(key, index, value);
return true;
}catch (Exception e){
LOGGER.info(e.getMessage());
return false;
}
}
/**
* 从指定list集合中移除和value相等的count个元素
* @param key
* @param count count>0 从表头到表尾搜索;count=0 移除所有和value相当的元素;count<0从表尾向表头搜索
* @param value
* @return
*/
public long lRemove(String key,long count,Object value){
try{
return redisTemplate.opsForList().remove(key, count, value);
}catch (Exception e){
LOGGER.info(e.getMessage());
return 0;
}
}
}
在试验前,记得启动Redis服务
Redis启动后,我写了一个方法来测试,我事先在Redis中已经放过数据,直接用Redis客户端存和用Java代码存的值,实际上是有区别的
Java代码存的:
直接用Redis客户端存的:
用客户端存的数据,如果用Java代码去读是会报错的,因为Java会将value的前后自动加上斜杠
然后,下面是我的测试方法:
@Autowired
private RedisUtil redisUtil;
@RequestMapping(value = "/getRedis",method = RequestMethod.POST)
@ResponseBody
public Map getRedisValue(){
Map<String,Object> resultMap = new HashMap<>();
List<Object> list = redisUtil.lRange("list2",0,-1);
list.stream().forEach(
x -> System.out.println(x)
);
resultMap.put("range",list);
return resultMap;
}
结果:
这里还有一点要注意的是:
直接启动Redis客户端时,Redis里面保存的中文会显示成这样
所以在启动客户端时,在后面加上–raw就正常了