1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.在spring配置文件中配置redis
spring:
redis:
# Redis服务器地址
host:
# Redis服务器端口号
port: 6379
# 使用的数据库索引,默认是0
database: 0
# 连接超时时间
timeout: 1800000
# 设置密码
password:
lettuce:
pool:
# 最大阻塞等待时间,负数表示没有限制
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 5
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中最大连接数,负数表示没有限制
max-active: 20
3.使用redis,如果直接使用redisTempalte
@Autowired
RedisTemplate redisTemplate;
@Test
void contextLoads() {
redisTemplate.opsForValue().set("n","1");
String name=(String)redisTemplate.opsForValue().get("n");
System.out.println(name);
}
那么在redis存储的全是二进制文件
\xAC\xED\x00\x05t\x00\x03123
4.所以需要一个配置类来进行序列化
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
// 创建模板
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer =
new GenericJackson2JsonRedisSerializer();
// key和 hashKey采用 string序列化
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// value和 hashValue采用 JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
}
这样存储的结果就不会显示为二进制文件了,但是在存储对象的时候就会出现新的问题,为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销.
5.所以使用String序列化器
@Autowired
private StringRedisTemplate redisTemplate;
// JSON工具
private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testOne() {
redisTemplate.opsForValue().set("name", "卷心菜");
}
@Test
void testTwo() throws IOException {
Person person = new Person("我是一棵卷心菜", 21);
// 手动序列化
String json = mapper.writeValueAsString(person);
redisTemplate.opsForValue().set("person", json);
String personJson = redisTemplate.opsForValue().get("person");
// 反序列化
Person person1 = mapper.readValue(personJson, Person.class);
System.out.println(person1);
}
6.或者直接使用这个类直接拿来用
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author wxl
* @date 2021-08-15 18:44
*/
@Slf4j
@Component
public class CacheService {
@Autowired
private StringRedisTemplate redisTemplate;
private final String DEFAULT_KEY_PREFIX = "";
private final int EXPIRE_TIME = 1;
private final TimeUnit EXPIRE_TIME_TYPE = TimeUnit.DAYS;
/**
* 数据缓存至redis
*
* @param key
* @param value
* @return
*/
public <K, V> void add(K key, V value) {
try {
if (value != null) {
redisTemplate
.opsForValue()
.set(DEFAULT_KEY_PREFIX + key, JSON.toJSONString(value));
}
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException("数据缓存至redis失败");
}
}
/**
* 数据缓存至redis并设置过期时间
*
* @param key
* @param value
* @return
*/
public <K, V> void add(K key, V value, long timeout, TimeUnit unit) {
try {
if (value != null) {
redisTemplate
.opsForValue()
.set(DEFAULT_KEY_PREFIX + key, JSON.toJSONString(value), timeout, unit);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException("数据缓存至redis失败");
}
}
/**
* 写入 hash-set,已经是key-value的键值,不能再写入为hash-set
*
* @param key must not be {@literal null}.
* @param subKey must not be {@literal null}.
* @param value 写入的值
*/
public <K, SK, V> void addHashCache(K key, SK subKey, V value) {
redisTemplate.opsForHash().put(DEFAULT_KEY_PREFIX + key, subKey, value);
}
/**
* 写入 hash-set,并设置过期时间
*
* @param key must not be {@literal null}.
* @param subKey must not be {@literal null}.
* @param value 写入的值
*/
public <K, SK, V> void addHashCache(K key, SK subKey, V value, long timeout, TimeUnit unit) {
redisTemplate.opsForHash().put(DEFAULT_KEY_PREFIX + key, subKey, value);
redisTemplate.expire(DEFAULT_KEY_PREFIX + key, timeout, unit);
}
/**
* 获取 hash-setvalue
*
* @param key must not be {@literal null}.
* @param subKey must not be {@literal null}.
*/
public <K, SK> Object getHashCache(K key, SK subKey) {
return redisTemplate.opsForHash().get(DEFAULT_KEY_PREFIX + key, subKey);
}
/**
* 从redis中获取缓存数据,转成对象
*
* @param key must not be {@literal null}.
* @param clazz 对象类型
* @return
*/
public <K, V> V getObject(K key, Class<V> clazz) {
String value = this.get(key);
V result = null;
if (!StringUtils.isEmpty(value)) {
result = JSONObject.parseObject(value, clazz);
}
return result;
}
/**
* 从redis中获取缓存数据,转成list
*
* @param key must not be {@literal null}.
* @param clazz 对象类型
* @return
*/
public <K, V> List<V> getList(K key, Class<V> clazz) {
String value = this.get(key);
List<V> result = Collections.emptyList();
if (!StringUtils.isEmpty(value)) {
result = JSONArray.parseArray(value, clazz);
}
return result;
}
/**
* 功能描述:Get the value of {@code key}.
*
* @param key must not be {@literal null}.
* @return java.lang.String
* @date 2021/9/19
**/
public <K> String get(K key) {
String value;
try {
value = redisTemplate.opsForValue().get(DEFAULT_KEY_PREFIX + key);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException("从redis缓存中获取缓存数据失败");
}
return value;
}
/**
* 删除key
*/
public void delete(String key) {
redisTemplate.delete(key);
}
/**
* 批量删除key
*/
public void delete(Collection<String> keys) {
redisTemplate.delete(keys);
}
/**
* 序列化key
*/
public byte[] dump(String key) {
return redisTemplate.dump(key);
}
/**
* 是否存在key
*/
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 设置过期时间
*/
public Boolean expire(String key, long timeout, TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
/**
* 设置过期时间
*/
public Boolean expireAt(String key, Date date) {
return redisTemplate.expireAt(key, date);
}
/**
* 移除 key 的过期时间,key 将持久保持
*/
public Boolean persist(String key) {
return redisTemplate.persist(key);
}
/**
* 返回 key 的剩余的过期时间
*/
public Long getExpire(String key, TimeUnit unit) {
return redisTemplate.getExpire(key, unit);
}
/**
* 返回 key 的剩余的过期时间
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
}