Springboot整合Redis
一.准备工作
1.1.安装redis
1.2.依赖导入
<!--在springboot 2.0版本后,spring-boot-starter-data-redis 提供了Lettuce代替Jedis.-->
<!--如果要使用Jedis, 就要在pom.xml中去掉Lettuce 并且添加 Jedis.-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
1.3.配置application.properties文件
#设置redis服务器的host或者ip地址,其他参数的注释详情见RedisConfig.java文件
universe.redis.hostName=192.168.10.100
universe.redis.port=6379
universe.redis.password=123456
universe.redis.database=0
universe.redis.pool.maxTotal=4
universe.redis.pool.maxIdle=4
universe.redis.pool.minIdle=1
universe.redis.pool.blockWhenExhausted=true
universe.redis.pool.maxWaitMillis=60000
universe.redis.pool.testOnBorrow=false
universe.redis.pool.testOnReturn=false
universe.redis.pool.jmxEnabled=true
universe.redis.pool.testWhileIdle=true
universe.redis.pool.timeBetweenEvictionRunsMillis=60000
universe.redis.pool.minEvictableIdleTimeMillis=120000
universe.redis.pool.numTestsPerEvictionRun=1
1.4.创建RedisConfig.java
package com.temperature.humidity.system.config.redis;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data
public class RedisConfig {
/**
* 设置redis服务器的host或者ip地址
*/
@Value("${universe.redis.hostName}")
private String hostName;
/**
* 设置redis的服务的端口号
*/
@Value("${universe.redis.port}")
private Integer port;
/**
* 设置密码
*/
@Value("${universe.redis.password}")
private String password;
/**
* 设置默认使用的数据库
*/
@Value("${universe.redis.database}")
private Integer database;
/**
* 资源池中的最大连接数
*/
@Value("${universe.redis.pool.maxTotal}")
private Integer maxTotal;
/**
* 资源池允许的最大空闲连接数
*/
@Value("${universe.redis.pool.maxIdle}")
private Integer maxIdle;
/**
* 资源池确保的最少空闲连接数
*/
@Value("${universe.redis.pool.minIdle}")
private Integer minIdle;
/**
* 当资源池用尽后,调用者是否要等待。只有当值为true时,
* 下面的maxWaitMillis才会生效。
*/
@Value("${universe.redis.pool.blockWhenExhausted}")
private Boolean blockWhenExhausted;
/**
* 当资源池连接用尽后,调用者的最大等待时间(单位为毫秒)。
*/
@Value("${universe.redis.pool.maxWaitMillis}")
private Long maxWaitMillis;
/**
* 向资源池借用连接时是否做连接有效性检测(ping)。
* 检测到的无效连接将会被移除。
*/
@Value("${universe.redis.pool.testOnBorrow}")
private Boolean testOnBorrow;
/**
* 向资源池归还连接时是否做连接有效性检测(ping)。
* 检测到无效连接将会被移除。
*/
@Value("${universe.redis.pool.testOnReturn}")
private Boolean testOnReturn;
/**
* 是否开启JMX监控
*/
@Value("${universe.redis.pool.jmxEnabled}")
private Boolean jmxEnabled;
/**
* 是否在空闲资源监测时通过ping命令监测连接有效性,
* 无效连接将被销毁。
*/
@Value("${universe.redis.pool.testWhileIdle}")
private Boolean testWhileIdle;
/**
* 空闲资源的检测周期(单位为毫秒)
*/
@Value("${universe.redis.pool.timeBetweenEvictionRunsMillis}")
private Long timeBetweenEvictionRunsMillis;
/**
* 资源池中资源的最小空闲时间(单位为毫秒),达到此值后空闲资源将被移除。
*/
@Value("${universe.redis.pool.minEvictableIdleTimeMillis}")
private Long minEvictableIdleTimeMillis;
/**
* 做空闲资源检测时,每次检测资源的个数。
*/
@Value("${universe.redis.pool.numTestsPerEvictionRun}")
private Integer numTestsPerEvictionRun;
}
1.5.创建OurRedis.java
package com.temperature.humidity.system.config.redis;
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 lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.jcache.config.JCacheConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.time.Duration;
@EnableCaching
@Configuration
@Log4j2
public class OurRedis extends JCacheConfigurerSupport {
@Autowired
private RedisConfig redisConfig;
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
log.info("开始初始redis -->redisTemplate");
RedisSerializer<Object> serializer = redisSerializer();
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置 redisTemplate 的序列化器
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
log.info("初始redis完成 -->redisTemplate");
return redisTemplate;
}
/**
* jedis连接工厂
*
* @param jedisPoolConfig
* @return
*/
@Bean
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
//单机版jedis
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(redisConfig.getHostName());
redisStandaloneConfiguration.setDatabase(redisConfig.getDatabase());
redisStandaloneConfiguration.setPassword(RedisPassword.of(redisConfig.getPassword()));
redisStandaloneConfiguration.setPort(redisConfig.getPort());
//获得默认的连接池构造器
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpccb =
(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
jpccb.poolConfig(jedisPoolConfig);
//通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpccb.build();
//单机配置 + 客户端配置 = jedis连接工厂
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(redisConfig.getMaxTotal());
jedisPoolConfig.setMaxIdle(redisConfig.getMaxIdle());
jedisPoolConfig.setMinIdle(redisConfig.getMinIdle());
jedisPoolConfig.setBlockWhenExhausted(redisConfig.getBlockWhenExhausted());
jedisPoolConfig.setMaxWaitMillis(redisConfig.getMaxWaitMillis());
jedisPoolConfig.setTestOnBorrow(redisConfig.getTestOnBorrow());
jedisPoolConfig.setTestOnReturn(redisConfig.getTestOnReturn());
jedisPoolConfig.setJmxEnabled(redisConfig.getJmxEnabled());
//空闲Jedis对象检测由下列四个参数组合完成。
jedisPoolConfig.setTestWhileIdle(redisConfig.getTestWhileIdle());
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(redisConfig.getTimeBetweenEvictionRunsMillis());
jedisPoolConfig.setMinEvictableIdleTimeMillis(redisConfig.getMinEvictableIdleTimeMillis());
jedisPoolConfig.setNumTestsPerEvictionRun(redisConfig.getNumTestsPerEvictionRun());
return jedisPoolConfig;
}
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
//设置Redis缓存有效期为1天
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer())).entryTtl(Duration.ofDays(1));
return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
}
public RedisSerializer<Object> redisSerializer() {
//创建JSON序列化器
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
serializer.setObjectMapper(objectMapper);
return serializer;
}
}
1.5.创建OurJedisUtil.java
package com.temperature.humidity.system.common.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class OurJedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 设置带过期时间的缓存
public Boolean set(String key, Object value, long time) {
return redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS);
}
// 设置缓存
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
// 根据 key 获得缓存
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
// 根据 key 删除缓存
public Boolean delete(String key) {
return redisTemplate.delete(key);
}
// 根据 keys 集合批量删除缓存
public Long delete(Set<String> keys) {
return redisTemplate.delete(keys);
}
// 根据正则表达式匹配 keys 获取缓存
public Set<String> getKeysByPattern(String pattern) {
return redisTemplate.keys(pattern);
}
public void hmput(String key, Map<String, Object> map) {
redisTemplate.opsForHash().putAll(key, map);
}
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
public Boolean expire(String key, long timeOut) {
return redisTemplate.expire(key, timeOut, TimeUnit.SECONDS);
}
}
二.测试
2.1.创建JedisTestController .java
我们首先点击如下所示的按钮启动我们的项目。
package com.temperature.humidity.system.common.utils.test;
import com.temperature.humidity.system.common.utils.OurJedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/test")
@RestController
public class JedisTestController {
@Autowired
private OurJedisUtil ourJedisUtil;
@RequestMapping("/jedis")
public String jedis(String key, String value) {
try {
ourJedisUtil.set(key, value);
return "成功";
} catch (Exception e) {
return "失败";
}
}
}
2.2.测试接口
我们的服务启动成功之后,打开postman输入http://127.0.0.1:8080/test/jedis?key=heyu&value=6666访问我们的jedis测试接口,我们可以看到服务器返回了发送成功的消息。
2.3.查看数据
我们启动完项目后登录我们的linux服务器输入如下命令进入用docker安装的redis容器内部
docker exec -it redis bash
我们输入如下命令连接服务器。
./usr/local/bin/redis-cli --raw -a 123456
我们输入如下命令查看我们刚刚用Jedis放进入的数据。
get heyu
可以看到key为heyu的value为6666,正是我们之前用Jedis放进入的数据。