pom依赖
引入redis的starter以及commons-pool2的依赖,commons-pool2是配置连接池需要使用的,不引入,只有连接池配置是不会创建连接池的
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
redis配置文件
这里使用lettuce作为演示
server.port=8080
# reids配置
spring.redis.client-type=lettuce
spring.redis.host=192.168.61.133
spring.redis.port=6379
spring.redis.password=123456
spring.redis.ssl=false
#超时时间 单位ms
spring.redis.timeout=100000
spring.redis.database=0
# 使用默认lettuce作为连接池,只有引入commons-pool2依赖才会创建连接池,仅有连接池配置不会创建连接池!
# 最大连接数
spring.redis.lettuce.pool.max-active=10
# 连接池中最大空闲连接
spring.redis.lettuce.pool.max-idel=3
# 连接池中最小空闲连接
spring.redis.lettuce.pool.min-idel=2
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
spring.redis.lettuce.pool.max-wait=60s
代码示例
这里将redis默认的序列化方式JdkSerializationRedisSerializer修改为了Jackson2JsonRedisSerializer,之所以要更换序列化方式,是因为默认的序列化方式,在redis中存储的数据无法直观看到其内容。但是更改了序列化方式后,存放的value只能是json格式,不能是纯字符串,如果是纯字符串,在取到数据后转换时会报错。
如果需要同时支持存储普通字符串,还需要同时创建StringRedisTemplate 的bean对象注入到容器中,这样就可以同时支持普通字符串和json形式的存储了。
个人感觉修改默认序列化方式不如直接使用stringRedisTemplate,把需要存的数据手动转为json字符串后再存入更好。
package com.example.lchtest.redis.tool;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
// 默认是 RedisTemplate<Object, Object>, 这里修改为key是string类型
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* value为字符串的redisTemplate
*
* @param connectionFactory
* @return stringRedisTemplate bean对象
*/
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}
redis工具类:
package com.example.lchtest.redis.tool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtil {
@Autowired
RedisTemplate<String,Object> redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
/**
* setex
* @param key key
* @param value value
* @param time 过期时间
*/
public void setex(String key,Object value,long time){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}
/**
* set
* String类型的set,无过期时间
* @param key key
* @param value value
*/
public void set(String key, Object value){
redisTemplate.opsForValue().set(key,value);
}
public void setStrValue(String key, String value){
stringRedisTemplate.opsForValue().set(key,value);
}
/**
* 批量设置key和value
* @param map key和value的集合
*/
public void mset(Map<String,Object> map){
redisTemplate.opsForValue().multiSet(map);
}
/**
* 如果key不存在,则设置
* @param key key
* @param value value
* @return 返回是否成功
*/
public Boolean setnx(String key,Object value){
return redisTemplate.opsForValue().setIfAbsent(key, value);
}
/**
* 批量插入key,如果key不存在的话
* @param map key和value的集合
* @return 是否成功
*/
public Boolean msetnx(Map<String,Object> map){
return redisTemplate.opsForValue().multiSetIfAbsent(map);
}
/**
* String类型的get
* @param key key
* @return 返回value对应的对象
*/
public Object get(String key){
return redisTemplate.opsForValue().get(key);
}
public Object getStrValue(String key){
return stringRedisTemplate.opsForValue().get(key);
}
/**
* 删除对应key
* @param key key
* @return 返回是否删除成功
*/
public Boolean del(String key){
return redisTemplate.delete(key);
}
/**
* 批量删除key
* @param keys key的集合
* @return 返回删除成功的个数
*/
public Long del(List<String> keys){
return redisTemplate.delete(keys);
}
/**
* 给某个key设置过期时间
* @param key key
* @param time 过期时间
* @return 返回是否设置成功
*/
public Boolean expire(String key, long time){
return redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
/**
* 返回某个key的过期时间
* @param key key
* @return 返回key剩余的过期时间
*/
public Long ttl(String key){
return redisTemplate.getExpire(key);
}
/**
* 返回是否存在该key
* @param key key
* @return 是否存在该key
*/
public Boolean exists(String key){
return redisTemplate.hasKey(key);
}
/**
* 给key的值加上delta值
* @param key key
* @param delta 参数
* @return 返回key+delta的值
*/
public Long incrby(String key, long delta){
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 给key的值减去delta
* @param key key
* @param delta 参数
* @return 返回key - delta的值
*/
public Long decrby(String key, long delta){
return redisTemplate.opsForValue().decrement(key, delta);
}
//hash类型
/**
* set hash类型
* @param key key
* @param hashKey hashKey
* @param value value
*/
public void hset(String key,String hashKey, Object value){
redisTemplate.opsForHash().put(key, hashKey, value);
}
/**
* set hash类型,并设置过期时间
* @param key key
* @param hashKey hashKey
* @param value value
* @param time 过期时间
* @return 返回是否成功
*/
public Boolean hset(String key, String hashKey,Object value, long time){
hset(key, hashKey, value);
return expire(key, time);
}
/**
* 批量设置hash
* @param key key
* @param map hashKey和value的集合
* @param time 过期时间
* @return 是否成功
*/
public Boolean hmset(String key, Map<String,Object> map, long time){
redisTemplate.opsForHash().putAll(key, map);
return expire(key, time);
}
/**
* 获取hash类型的值
* @param key key
* @param hashKey hashKey
* @return 返回对应的value
*/
public Object hget(String key, String hashKey){
return redisTemplate.opsForHash().get(key, hashKey);
}
/**
* 获取key下所有的hash值以及hashKey
* @param key key
* @return 返回数据
*/
public Map<Object,Object> hgetall(String key){
return redisTemplate.opsForHash().entries(key);
}
/**
* 批量删除
* @param key key
* @param hashKey hashKey数组集合
*/
public void hdel(String key, Object... hashKey){
redisTemplate.opsForHash().delete(key, hashKey);
}
/**
* 判断是否存在hashKey
* @param key key
* @param hashKey hashKey
* @return 是否存在
*/
public Boolean hexists(String key, String hashKey){
return redisTemplate.opsForHash().hasKey(key, hashKey);
}
}
测试类:
package com.example.lchtest.redis.test;
import com.alibaba.fastjson.JSON;
import com.example.lchtest.redis.tool.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@RestController
public class RedisTestController {
@Autowired
RedisUtil redisUtil;
@GetMapping("/save")
public String save(String key, String value){
redisUtil.setStrValue(key, value);
return "OK";
}
@GetMapping("/saveJsonStr")
public String save(){
User user2 = new User();
user2.setName("tom");
user2.setAge(23);
redisUtil.setStrValue("userJson", JSON.toJSONString(user2));
return "OK";
}
@GetMapping("/getvalue")
public String save(String key){
Object value = redisUtil.getStrValue(key);
return Objects.isNull(value) ? "NULL" : (String)value;
}
@GetMapping("/saveJson")
public String saveJson(){
User user = new User();
user.setAge(20);
user.setName("jack");
User user2 = new User();
user2.setName("tom");
user2.setAge(23);
List<User> userList = Arrays.asList(user, user2);
redisUtil.set("user", user);
redisUtil.set("userList", userList);
return JSON.toJSONString(redisUtil.get("user"));
}
}
数据库中存储的数据格式:
使用Jackson2JsonRedisSerializer序列化后存储的对象:
使用Jackson2JsonRedisSerializer序列化后存储的list:
对象手动转换为json串后存储:
代码地址:
https://gitee.com/liuch890228/springboot/tree/master/springbootdemo/springboot-demo8-redis