【前言】针对系统中的查询比较频繁的热点数据做缓存,注意不是类似数据库的二级缓存哦,spring的Cacheable这个注解可以对方法级别的返回值直接缓存,还可以在类上打该注解
springboot 版本 2.1.5.RELEASE
1.引入redis
org.springframework.boot spring-boot-starter-data-redis
2.application.yml
spring: redis: host: 127.0.0.1 database: 1 port: 6379 password: timeout: 5000 jedis: pool: max-active: 20 max-idle: 20 min-idle: 10 max-wait: -1ms
3.配置Redisconfig
package com.lkx.springbootfull.redis;import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.cache.RedisCacheManager;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.RedisSerializationContext;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;/** * ClassName: RedisConfig * Function: TODO * Date: 2019-06-07 15:13 * author likaixuan * version V1.0 */@Configurationpublic class RedisConfig { private Duration timeToLive = Duration.ofHours(1); @Bean public RedisTemplate
4.RedisUtils 这个如果是缓存的话可有可无,系统中redis get set操作的公共类
package com.lkx.springbootfull.redis;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.*;import org.springframework.stereotype.Component;import java.io.Serializable;import java.util.List;import java.util.Set;import java.util.concurrent.TimeUnit;/** * ClassName: RedisUtils * Function: TODO * Date: 2019-06-07 16:49 * author likaixuan * version V1.0 */@Componentpublic class RedisUtils { @Autowired private RedisTemplate redisTemplate;//不带事务 /** * 写入缓存 * * @param key * @param value * @return */ public boolean set(final String key, Object value) { boolean result = false; try { ValueOperationsoperations = redisTemplate.opsForValue(); operations.set(key, value); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 写入缓存设置时效时间 * * @param key * @param value * @return */ public boolean set(final String key, Object value, Long expireTime) { boolean result = false; try { ValueOperations operations = redisTemplate.opsForValue(); operations.set(key, value); redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 批量删除对应的value * * @param keys */ public void remove(final String... keys) { for (String key : keys) { remove(key); } } /** * 批量删除对应的value (带事务,业务代码中用到事务,则需用此方法) * * @param keys */ public void removeTransactional(final String... keys) { for (String key : keys) { removeTransactional(key); } } /** * 批量删除key * * @param pattern */ public void removePattern(final String pattern) { Set keys = redisTemplate.keys(pattern); if (keys.size() > 0) redisTemplate.delete(keys); } /** * 删除对应的value * * @param key */ public void remove(final String key) { if (exists(key)) { redisTemplate.delete(key); } } /** * 判断缓存中是否有对应的value * * @param key * @return */ public boolean exists(final String key) { return redisTemplate.hasKey(key); } /** * 读取缓存 * * @param key * @return */ public Object get(final String key) { ValueOperations operations = redisTemplate.opsForValue(); return operations.get(key); } /** * 哈希 添加 * * @param key * @param hashKey * @param value */ public void hmSet(String key, Object hashKey, Object value) { HashOperations hash = redisTemplate.opsForHash(); hash.put(key, hashKey, value); } /** * 哈希获取数据 * * @param key * @param hashKey * @return */ public Object hmGet(String key, Object hashKey) { HashOperations hash = redisTemplate.opsForHash(); return hash.get(key, hashKey); } /** * 列表添加 * * @param k * @param v */ public void lPush(String k, Object v) { ListOperations list = redisTemplate.opsForList(); list.rightPush(k, v); } /** * 列表获取 * * @param k * @param l * @param l1 * @return */ public List lRange(String k, long l, long l1) { ListOperations list = redisTemplate.opsForList(); return list.range(k, l, l1); } /** * 集合添加 * * @param key * @param value */ public void add(String key, Object value) { SetOperations set = redisTemplate.opsForSet(); set.add(key, value); } /** * 集合获取 * * @param key * @return */ public Set setMembers(String key) { SetOperations set = redisTemplate.opsForSet(); return set.members(key); } /** * 有序集合添加 * * @param key * @param value * @param scoure */ public void zAdd(String key, Object value, double scoure) { ZSetOperations zset = redisTemplate.opsForZSet(); zset.add(key, value, scoure); } /** * 有序集合获取 * * @param key * @param scoure * @param scoure1 * @return */ public Set rangeByScore(String key, double scoure, double scoure1) { ZSetOperations zset = redisTemplate.opsForZSet(); return zset.rangeByScore(key, scoure, scoure1); } /** * 加锁 * * @param key * @return */ public boolean tryLock(String key) { try { long currTime = System.currentTimeMillis(); //加锁成功 return redisTemplate.opsForValue().setIfAbsent(key, currTime); } finally { redisTemplate.expire(key, 5, TimeUnit.SECONDS); } }}
5.然后直接在方法上打上注解
key 如果不写的话,就会根据参数来自已生成相关key,如果指定了key,就是固定的key.
【注意】缓存时间内,该方法直接跳过,不执行该方法。