#yyds干货盘点# redis | 十四springboot整合redis

Posted anyoneElse

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点# redis | 十四springboot整合redis相关的知识,希望对你有一定的参考价值。


公众号:雨中散步撒哈拉

文章同步公众号,共同学习进步

个人网站:​​https://liudongdong.top​

文章来源:​​https://liudongdong.top/archives/redisshi-si-springboot-zheng-he-redis​


一、创建springboot项目

1. 创建项目springboot_redis

#yyds干货盘点#

2. pom文件

<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-redis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

3. 创建配置文件

spring.redis.host=127.0.0.1
spring.redis.port=6379

二、源码探究

基于spring-data-redis,并且没有使用 jedis,SpringBoot 2.x 之后,原来使用的 jedis 被替换为了 lettuce。

  1. jedis :采用直接连接方式,多个线程进行操作时是不安全的 ( 可能会有诸如忘记关闭连接导致开销增大等因素 ),因此可以使用 jedisPool 进行管理
  2. lettuce:底层代用 netty,实例可以在多个线程中进行共享,不存在线程不安全的情况,同时高效

1. 查看源码pom文件

pom文件,ctrl+点击spring-boot-starter-data-redis,跳转到具体底层pom文件。

#yyds干货盘点#

发现springboot是spring-data-redis进行实现,进入spring-data-redis配置文件,实现方式有俩种一个为jedis,另一个为lettuce。

#yyds干货盘点#

2. 查看源码properties

引入jar包中找到autoconfigure包,打开spring-autoconfigure-metadata.properties配置文件。搜索redis相关配置。

#yyds干货盘点#

进入RedisAutoConfiguration

#yyds干货盘点#

redis模板和常用string类型模板

#yyds干货盘点#

模板实现方式有俩种,一种是jedis,一种是lettuce 点击进入,可以看到实现类有俩种

#yyds干货盘点##yyds干货盘点#

而jedis实现方式已经放弃

#yyds干货盘点#

三、调用redis模板,进行操作

1. 调用默认模板

注入默认redis模板,进行调用,发现模板已经进行了封装,封装如下:

#yyds干货盘点#

package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@SpringBootTest
class SpringbootRedisApplicationTests
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads()
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
valueOperations.set("hello", "world");
System.out.println(valueOperations.get("hello"));

#yyds干货盘点#

2. 调用自定义模板

1. 自定义模板

package com.example.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
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;
import java.net.UnknownHostException;
@Configuration
public class RedisConfig
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//JSON 序列化配置
Jackson2JsonRedisSerializer jacksonSerializer = new Jackson2JsonRedisSerializer(Object.class);
//配置默认序列化方式,Object.class 表示可以序列化所有对象
template.setDefaultSerializer(jacksonSerializer);
//使用 om 进行进一步配置
ObjectMapper om = new ObjectMapper();
//配置所有字段都可以被序列化,而不仅仅是 public (默认就是全都序列化的)
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//用于指定序列化的实际类型是否符合要求,这里的要求非 final 修饰的类
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSerializer.setObjectMapper(om);
//String 序列化
StringRedisSerializer stringSerializer = new StringRedisSerializer();
//对于源码中的两种 key 使用 string 方式序列化
template.setKeySerializer(stringSerializer);
template.setHashKeySerializer(stringSerializer);
//对于源码中的两种 value 使用 json 方式序列化
template.setValueSerializer(jacksonSerializer);
template.setHashValueSerializer(jacksonSerializer);
return template;

2. 调用自定义注解

#yyds干货盘点#

package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@SpringBootTest
class SpringbootRedisApplicationTests
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate redisTemplate;
@Test
void contextLoads()
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
valueOperations.set("hello", "世界你好");
System.out.println(valueOperations.get("hello"));

四、工具类

package com.example;
import com.example.config.RedisConfig;
import com.example.util.RedisUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@SpringBootTest
class SpringbootRedisApplicationTests
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate redisTemplate;
@Autowired
RedisUtil redisUtil;
@Test
void contextLoads()
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
valueOperations.set("hello", "世界你好");
System.out.println(valueOperations.get("hello"));

@Test
void utilTest()
redisUtil.set("utilTest", "测试");
System.out.println(redisUtil.get("utilTest"));

结果输出

#yyds干货盘点#

附录

RedisUtil工具类

package com.example.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public final class RedisUtil
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// =============================common============================
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
*/
public boolean expire(String key, long time)
try
if (time > 0)
redisTemplate.expire(key, time, TimeUnit.SECONDS);

return true;
catch (Exception e)
e.printStackTrace();
return false;


/**
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key)
return redisTemplate.getExpire(key, TimeUnit.SECONDS);

/**
* 判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key)
try
return redisTemplate.hasKey(key);
catch (Exception e)
e.printStackTrace();
return false;


/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key)
if (key != null && key.length > 0)
if (key.length == 1)
redisTemplate.delete(key[0]);
else
redisTemplate.delete(String.valueOf(CollectionUtils.arrayToList(key)));



// ============================String=============================
/**
* 普通缓存获取
*
* @param key 键
* @return 值
*/
public Object get(String key)
return key == null ? null : redisTemplate.opsForValue().get(key);

/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value)
try
redisTemplate.opsForValue().set(key, value);
return true;
catch (Exception e)
e.printStackTrace();
return false;


/**
* 普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time)
try
if (time > 0)
redisTemplate.opsForValue().set(key, value, time,
TimeUnit.SECONDS);
else
set(key, value);

return true;
catch (Exception e)
e.printStackTrace();
return false;


/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
*/
public long incr(String key, long delta)
if (delta < 0)
throw new RuntimeException("递增因子必须大于0");

return redisTemplate.opsForValue().increment(key, delta);

/**
* 递减
*
* @param key 键
* @param delta 要减少几(小于0)
*/
public long decr(String key, long delta)
if (delta < 0)
throw new RuntimeException("递减因子必须大于0");

return redisTemplate.opsForValue().increment(key, -delta);

// ================================Map=================================
/**
* HashGet
*
* @param key 键 不能为null
* @param item 项 不能为null
*/
public Object hget(String key, String item)
return redisTemplate.opsForHash().get(key, item);

/**
* 获取hashKey对应的所有键值
*
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key)
return redisTemplate.opsForHash().entries(key);

/**
* HashSet
*
* @param key 键
* @param map 对应多个键值
*/
public boolean hmset(String key, Map<String, Object> map)
try
redisTemplate.opsForHash().putAll(key, map);
return true;
catch (Exception e)
e.printStackTrace();
return false;


/**
* HashSet 并设置时间
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(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)
e.printStackTrace();
return false;


/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value)
try
redisTemplate.opsForHash().put(key, item, value);
return true;
catch (Exception e)
e.printStackTrace();
return false;


/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time)
try
redisTemplate.opsForHash().put(key, item, value);
if (time > 0)
expire(key, time);

return true;
catch (Exception e)
e.printStackTrace();
return false;


/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item)
redisTemplate.opsForHash().delete(key, item);

/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item)
return redisTemplate.opsForHash().hasKey(key, item);

/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
*/
public double hincr(String key, String item, double by)
return redisTemplate.opsForHash().increment(key, item, by);

/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
*/
public double hdecr(String key, String item, double by)
return redisTemplate.opsForHash().increment(key, item, -by);

// ============================set=============================
/**
* 根据key获取Set中的所有值
*
* @param key 键
*/
public Set<Object> sGet(String key)
try
return redisTemplate.opsForSet().members(key);
catch (Exception e)
e.printStackTrace();
return null;


以上是关于#yyds干货盘点# redis | 十四springboot整合redis的主要内容,如果未能解决你的问题,请参考以下文章

#yyds干货盘点# 前端歌谣的刷题之路-第九十四题-数组过滤

#yyds干货盘点# 前端歌谣的刷题之路-第五十四题-字符串搜索

#yyds干货盘点 前端歌谣的刷题之路-第十四题-设置盒子的一个宽和高

#yyds干货盘点#--redis-2

#yyds干货盘点# Redis概念和基础

#yyds干货盘点# 前端歌谣的刷题之路-第六十四题-查找元素位置前端歌谣的刷题之路-第六十四题-查找元素位置