Redis入门级操作实例
需求:展示用户最近的五条搜索记录,最新搜索的记录放在前面,使用缓存技术
Redis配置
package com.linshang.weixin.external.cache.config;
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.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @Description redis配置
* @Author SunHui
* @Date 2021/4/15 1:53 下午
*/
@Configuration
public class RedisConfig {
@Bean(name = "redisTemplateCustom")
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
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的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
Redis依赖
<!-- pom文件中加入redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
Redis工具类
package com.linshang.weixin.common.utils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
public final class RedisUtils {
@Resource(name = "redisTemplateCustom")
private RedisTemplate<String, Object> redisTemplate;
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
}
/**
* 判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
}
/**
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}
/**
* 普通缓存放入并设置时间
*
* @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 键
* @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;
}
}
/**
* 获取list缓存的长度
*
* @param key 键
* @return
*/
public long lGetListSize(String key) {
return redisTemplate.opsForList().size(key);
}
/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
}
/**
* 将list放入左边缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lLeftPush(String key, Object value, long time) {
try {
redisTemplate.opsForList().leftPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list最右边位置弹出
*
* @param key 键
* @return
*/
public Boolean lRightPop(String key) {
try {
redisTemplate.opsForList().rightPop(key);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashGet
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 对value值自增数目
* @param keyName 键值
* @param number 自增数值
*/
public Long increment(String keyName, Long number) {
return redisTemplate.opsForValue().increment(keyName, number);
}
public Boolean setIfAbsent(String redisName, long currentTimeMillis, Long betweenTime, TimeUnit timeUnit) {
return redisTemplate.opsForValue().setIfAbsent(redisName, currentTimeMillis,
betweenTime, timeUnit);
}
}
Redis代码
Redis键名设置
package com.linshang.weixin.external.cache.constant;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
/**
* @Description
* @Auther SunHui
* @Date 2021/4/15 1:46 下午
*/
@Data
public class RedisKey {
// 项目名
public static final String PROJECT_PREFIX = "LIN_SHANG_GOODS";
// 用户id
public String appId;
public RedisKey(String appId) {
this.appId = appId;
}
public String getRedisKeyName() {
if (StringUtils.isNotBlank(appId)) {
return PROJECT_PREFIX + ":" + appId;
}
return PROJECT_PREFIX ;
}
}
Redis业务层
package com.linshang.weixin.external.cache.service;
import com.linshang.weixin.common.utils.RedisUtils;
import com.linshang.weixin.external.cache.constant.RedisKey;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @Description
* @ClassName SearchKey
* @Author SunHui
* @Date 2021/4/15 1:59 下午
*/
@Component
public class SearchKeyRedis {
public final static int LENGTH = 5;
@Resource
private RedisUtils redisUtils;
// 根据key搜索,返回list
public List<Object> searchKey(String appId) {
RedisKey redisKey = new RedisKey(appId);
List<Object> objectResult = redisUtils.lGet(redisKey.getRedisKeyName(), 0, LENGTH);
if (CollectionUtils.isNotEmpty(objectResult)) {
return objectResult;
}
return new ArrayList<>();
}
// 将value添加缓存
public boolean addKey(String appId, String value) {
RedisKey redisKey = new RedisKey(appId);
Long size = redisUtils.lGetListSize(redisKey.getRedisKeyName());
if (size >= LENGTH) {
// 大于指定个数移除最后一个,塞入第一个
redisUtils.lRightPop(redisKey.getRedisKeyName());
}
return redisUtils.lLeftPush(redisKey.getRedisKeyName(), value, 0);
}
// 缓存中删除value
public boolean delKey(String appId, String value) {
RedisKey redisKey = new RedisKey(appId);
redisUtils.lRemove(redisKey.getRedisKeyName(), 1, value);
return true;
}
// 判断缓存中是否存在该value
public boolean existKey(String appId, String value){
RedisKey redisKey = new RedisKey(appId);
List<Object> list = redisUtils.lGet(redisKey.getRedisKeyName(), 0, LENGTH);
for (Object object : list){
if (object.equals(value)) {
return true;
}
}
return false;
}
}
控制层代码
商品搜索接口部分代码
// 判断缓存中是否有该条记录,有则删除新增,即更新,将其前置,满足最近搜索的排在前面;无该记录新增处理
if (!StringUtils.isEmpty(request.getKeyWord())) {
boolean isExist = searchKeyRedis.existKey(idInfoDto.getAppId(), request.getKeyWord());
if (isExist) {
searchKeyRedis.delKey(idInfoDto.getAppId(), request.getKeyWord());
}
searchKeyRedis.addKey(idInfoDto.getAppId(), request.getKeyWord());
}
获取所有记录接口部分代码
/**
* @Description 获取搜索记录接口-展示最近五条记录:从redis缓存取
* @Author SunHui
* @Date 2021/4/15 11:42 上午
*/
@GetMapping("/goods/search/list")
public ResultData searchList() {
ResultData resultData = new ResultData(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMsg());
IDInfoDto infoDto = IDUtil.getIdByActive();
List<Object> searchList = searchKeyRedis.searchKey(infoDto.getAppId());
resultData.addData("searchList", searchList);
return resultData;
}
Redis Desktop Manager
如下图所示:我所测试的五个商品关键字,最近搜索的会添加到队列中,展示在最前面。