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 {@Beanpublic 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序列化方式采用jacksonredisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksonredisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}/*** value为字符串的redisTemplate** @param connectionFactory* @return stringRedisTemplate bean对象*/@Beanpublic 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 {@AutowiredRedisTemplate<String,Object> redisTemplate;@AutowiredStringRedisTemplate 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 {@AutowiredRedisUtil 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