首页 > 编程知识 正文

java判断map是否含有key,java获取map的key和value

时间:2023-05-06 05:03:50 阅读:17523 作者:2473

虽然以前就集成了SpringCache redis缓存数据,但在此项目的缓存中存在禁用缓存清除的问题。 我花了时间好好整理了一下。 主要是对@CacheEvict的key模糊匹配的支持。 熟悉redis命令的人知道查询和删除都可以进行模糊匹配,因此我们希望SpringCache也支持模糊匹配的清除。

契机是,由于缓存了向外部公开的API接口,API需要支持分页,因此在@Cacheable的key中,在current (当前页码)和classify (分类)中进行了匹配。 更改数据集时,每次删除所有分类的所有密钥都有点不合理。 如果只是更改了数据并针对某个分类清理密钥,key

开始行动,调查SpringCache的源代码和原理,具体可以在网上查找。 我只想说重点。

找到RedisCache中的evict后,对应于@CacheEvict的最终执行方法。 看到下面有clear方法,使用了模糊匹配的批量清除。 我觉得有点戏。

/**(non-JavaDoc ) @ see org.spring framework.cache.cache # evict ) Java.lang.object )/@ override公共语音///

}

/* * (非javadoc ) @ see org.spring framework.cache.cache # clear ) (*/@Overridepublic voidclear () ) ) )

byte [ ] pattern=conversion service.convert (create cachekey )、byte[].class );

cachewriter.clean(name,pattern ); //clean支持模糊匹配。 这是扩张时的重点

}

1 .先写RedisCache的子类,实际代替RedisCache

publicclasscustomizedrediscacheextendsrediscache {

私密金融字符串名称;

私有金融体系;

私密性转换服务;

protectedcustomizedrediscache (string name,RedisCacheWriter cacheWriter,rediscacheconfigurationcacheconfig ) super ) name

this.name=name;

this.cacheWriter=cacheWriter;

this.conversion service=cache config.getconversionservice (;

}

@ overridepublicvoidevict (object key ) if ) keyinstanceofstring ) {String keyString=key.toString;

if (string utils.endswith (密钥字符串,' * ' ) Evictlikesuffix (密钥字符串) );

返回;

} if (string utils.starts with (key string,' * ' ) evictlikeprefix (key string ) );

返回;

}super.evict(key );

}

/***前缀匹配* @ param key */publicvoidevictlikeprefix (string key ) byte [ ] pattern=this.conversion service.convert

this.cache writer.clean (this.name,pattern );

}

/***匹配后缀* @ param key */publicvoidevictlikesuffix (string key ) byte (pattern=) byte ) ) this.conversionservice

this.cache writer.clean (this.name,pattern );

}

//不需要前后一致的,直接allEntries=true

}

2 .如何让定制的客户参与进来

换RedisCache,还必须弄个RedisCacheManager的子类,RedisCache的创建过程是在manager中

public classCustomizedRedisCacheManager extendsRedisCacheManager {

private finalRedisCacheWriter cacheWriter;

private finalRedisCacheConfiguration defaultCacheConfig;

private finalMapinitialCaches= newLinkedHashMap<>();

private booleanenableTransactions;

publicCustomizedRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {super(cacheWriter, defaultCacheConfiguration);

this.cacheWriter= cacheWriter;

this.defaultCacheConfig= defaultCacheConfiguration;

}

publicCustomizedRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, String... initialCacheNames) {super(cacheWriter, defaultCacheConfiguration, initialCacheNames);

this.cacheWriter= cacheWriter;

this.defaultCacheConfig= defaultCacheConfiguration;

}

publicCustomizedRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, booleanallowInFlightCacheCreation, String... initialCacheNames) {super(cacheWriter, defaultCacheConfiguration, allowInFlightCacheCreation, initialCacheNames);

this.cacheWriter= cacheWriter;

this.defaultCacheConfig= defaultCacheConfiguration;

}

publicCustomizedRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, MapinitialCacheConfigurations) {super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations);

this.cacheWriter= cacheWriter;

this.defaultCacheConfig= defaultCacheConfiguration;

}

publicCustomizedRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, MapinitialCacheConfigurations, booleanallowInFlightCacheCreation) {super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations, allowInFlightCacheCreation);

this.cacheWriter= cacheWriter;

this.defaultCacheConfig= defaultCacheConfiguration;

}

/**

* 这个构造方法最重要

**/

publicCustomizedRedisCacheManager(RedisConnectionFactory redisConnectionFactory, RedisCacheConfiguration cacheConfiguration) {this(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),cacheConfiguration);

}

//覆盖父类创建RedisCache

@OverrideprotectedRedisCache createRedisCache(String name, @NullableRedisCacheConfiguration cacheConfig) {return newCustomizedRedisCache(name, cacheWriter, cacheConfig != null? cacheConfig : defaultCacheConfig);

}

@OverridepublicMapgetCacheConfigurations() {MapconfigurationMap = newHashMap<>(getCacheNames().size());

getCacheNames().forEach(it -> {RedisCache cache = CustomizedRedisCache.class.cast(lookupCache(it));

configurationMap.put(it, cache != null? cache.getCacheConfiguration(): null);

});

returnCollections.unmodifiableMap(configurationMap);

}}

3.配置

/*** 缓存的序列化*@param*@paramredisConnectionFactory*@return*/@BeanpublicCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {ObjectMapper objectMapper = newObjectMapper();

RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(60*60)).disableCachingNullValues().computePrefixWith(cacheName -> "demo".concat(":").concat(cacheName).concat(":")).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(newStringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(createjkdwd2JsonRedisSerializer(objectMapper)));

return newCustomizedRedisCacheManager(redisConnectionFactory,cacheConfiguration);

//改变CacheManager的创建方式,原方式如下

// returnRedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build();

}

privateRedisSerializercreatejkdwd2JsonRedisSerializer(ObjectMapper objectMapper) {//TODO Auto-generated method stubjkdwd2JsonRedisSerializerserializer = newjkdwd2JsonRedisSerializer(Object.class);

objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

serializer.setObjectMapper(objectMapper);

returnserializer;

}

经过3步对RedisCache和RedisCacheManager后,运行后使用的就是自定义的CustomizedRedisCache和CustomizedRedisCacheManager了,是不是很简单。但实际是看完了整个SpringCache原理后做的最小改动。

使用@Cacheable比如: @Cacheable(value="demo", key="T(String).valueOf(#page.current).concat('-classify').concat(#classify)")

使用@CacheEvict就可以:@CacheEvict(value = "demo", key="'*-classify'.concat(#classify)"),删除指定classify的所有分页缓存数据

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。