redis模糊查找

原文链接:https://www.cnblogs.com/commissar-Xia/p/7759484.html


最近使用Redis优化项目功能,其中有一部分为模糊查询,找了很多帖子,也没有找到很好的解决方案和思路,最终皇天不负有心人啊,终于让我找到了!!!

感谢该帖作者:WalkerAlone  原文链接:http://blog.csdn.net/qq_28893679/article/details/53005057

可以通过Redis中keys命令进行获取key值,具体命令格式:keys pattern 

文中提到redis中允许模糊查询的有3个通配符,分别是:*,?,[]

其中:

*:通配任意多个字符

?:通配单个字符

[]:通配括号内的某一个字符

=========================================================================

在实际项目中有可能会使用spring集成redis的RedisTemplate进行操作,这样在注入模板时可能会出现模糊查询不好用的情况,是因为

keys方法是存在于StringRedisTemplate子类中(父类-RedisTemplate)的

在spring配置时,一定要注意!!!

=========================================================================

实际操作中具体的思路:

1. 将要查询的条件当做key进行ZSet存储

2. 在获取时,调用StringRedisTemplate.keys(pattern),例:

1
2
3
4
5
public  Set keys(String pattern){
   return  stringRedisTemplate.keys( "*"  + pattern +  "*" );
    // return stringRedisTemplate.keys("?" + pattern);
   // return stringRedisTemplate.keys("[" + pattern + "]");
}


ps:模糊查找适用于 String数据结构,对redis支持的其他结构(List、set等),没有 验证是否支持。


实践代码:

/**
 * redis缓存操作类
 */
@Service
public class RedisCacheService implements InitializingBean {

	private ValueOperations<String, String> valueOperations;

	@Autowired
	private StringRedisTemplate redisTemplate;

	@SuppressWarnings("unchecked")
	@Override
	public void afterPropertiesSet() throws Exception {
		RedisSerializer<String> redisSerializer = new StringRedisSerializer();
		valueOperations = redisTemplate.opsForValue();
	}

	/**
	 * 从缓存中获取资源信息
	 * @param key
	 * @return
	 */
	public List<ResourceCacheBO> getCacheResource(String key) {
		Set<String> keys = redisTemplate.keys(key);
		if (CollectionUtils.isEmpty(keys)) {
			return new ArrayList<>();
		}

		List<ResourceCacheBO> resourceCacheBOList = new ArrayList<>();
		for (String accurateKey : keys) {
			String cacheValue = valueOperations.get(accurateKey);
			List<ResourceCacheBO> sub = JSONArray.parseArray(cacheValue, ResourceCacheBO.class);
			resourceCacheBOList.addAll(sub);
		}

		return resourceCacheBOList;
	}

遇到问题:存在key:“A_091_JPFX”,但是用 模糊key:“A_*_JPFX”匹配时,却匹配不到;有资料说是编码问题,按下面方式解决:

原文链接:

redisTemplate.keys(pattern)模糊查询找不到keys:https://blog.csdn.net/cutterwolf/article/details/77990112


在使用redisTemplate.keys查找keys时,发现明明相应的key是存在的,模糊查询就是查找不出来;原因有二: 
1.确定你的查询字符串是否正确 
2.就是的你key值有可能是乱码了就是遇到\xca\xed加上你key之类的乱码!例如:这里写图片描述 
你需要重新定义key

 @Bean  
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {  
       RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();  
       redisTemplate.setConnectionFactory(factory);  

       //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;  
       //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer  
       //或者JdkSerializationRedisSerializer序列化方式;  
     RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;  
     redisTemplate.setKeySerializer(redisSerializer);  
     redisTemplate.setHashKeySerializer(redisSerializer);  

       return redisTemplate;  
    }   


完整代码:

package cn.xxt.word.analysis.service;

import cn.xxt.ssm.commons.exception.BizException;
import cn.xxt.ssm.commons.json.JacksonJsonUtil;
import cn.xxt.word.analysis.pojo.bo.QuestCacheBO;
import cn.xxt.word.analysis.pojo.bo.ResourceCacheBO;
import com.alibaba.fastjson.JSONArray;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * redis缓存操作类
 */
@Service
public class RedisCacheService implements InitializingBean {

	private ValueOperations<String, String> valueOperations;

	@Autowired
	private StringRedisTemplate redisTemplate;

	@SuppressWarnings("unchecked")
	@Override
	public void afterPropertiesSet() throws Exception {
		RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;
		redisTemplate.setKeySerializer(redisSerializer);
		redisTemplate.setHashKeySerializer(redisSerializer);
		valueOperations = redisTemplate.opsForValue();
	}

	/**
	 * 缓存资源
	 * @param key
	 * @param resourceCacheBOList
	 */
	public void cacheResource(String key, List<ResourceCacheBO> resourceCacheBOList) {
		// 参数校验
		if (CollectionUtils.isEmpty(resourceCacheBOList)) {
			throw new BizException(1, "参数有误");
		}
		// 缓存
		String resourceCacheValue = JacksonJsonUtil.objectToString(resourceCacheBOList);
		valueOperations.set(key, resourceCacheValue);
	}

	/**
	 * 从缓存中获取资源信息
	 * @param key
	 * @return
	 */
	// TODO 待测试
	public List<ResourceCacheBO> getCacheResource(String key) {
		Set<String> keys = redisTemplate.keys(key);
		if (CollectionUtils.isEmpty(keys)) {
			return new ArrayList<>();
		}

		List<ResourceCacheBO> resourceCacheBOList = new ArrayList<>();
		for (String accurateKey : keys) {
			String cacheValue = valueOperations.get(accurateKey);
			List<ResourceCacheBO> sub = JSONArray.parseArray(cacheValue, ResourceCacheBO.class);
			resourceCacheBOList.addAll(sub);
		}

		return resourceCacheBOList;
	}

	/**
	 * 缓存 关键字的编码
	 * @param key
	 * @return
	 */
	public void cacheKeyWordCode(String key, String code) {
		// 参数校验
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(code)) {
			throw new BizException(1, "参数有误");
		}
		// 缓存
		valueOperations.set(key, code);
	}

	/**
	 * 获取 关键字的编码
	 * @param key
	 * @return
	 */
	public String getKeyWordCode(String key) {
		String keyWordCode = valueOperations.get(key);
		if (StringUtils.isEmpty(keyWordCode)) {
			return null;
		} else {
			return keyWordCode;
		}
	}

	/**
	 * 批量获取 关键字的编码
	 * @param keys
	 * @return
	 */
	public List<String> batchGetKeyWordCode(List<String> keys) {
		List<String> codes = valueOperations.multiGet(keys);
		if (CollectionUtils.isEmpty(codes)) {
			return new ArrayList<>();
		} else {
			codes.removeAll(Collections.singleton(null));
			return codes;
		}
	}

}


猜你喜欢

转载自blog.csdn.net/zhaipengfei1231/article/details/80819454