SpringBoot整合Redis
1、引入pom
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
2、配置RedisTemplate
import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.cache.CacheManager;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.StringRedisSerializer;import java.time.Duration;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set;@Configurationpublic class RedisTemplateConfig { @Bean("redisTemplate") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); // 设置连接工厂 template.setConnectionFactory(connectionFactory); // 设置序列化方式 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key序列化 template.setKeySerializer(stringRedisSerializer); // value序列化 template.setValueSerializer(getJackson2JsonRedisSerializer()); // Hash key序列化 template.setHashKeySerializer(stringRedisSerializer); // Hash value序列化 template.setHashValueSerializer(getJackson2JsonRedisSerializer()); template.afterPropertiesSet(); return template; } /** * 缓存管理器 * * @param redisConnectionFactory * @return */ @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig(); // 设置缓存管理器管理 defaultCacheConfig = defaultCacheConfig // 缓存的默认过期时间: .entryTtl(Duration.ofSeconds(36000)) // 设置 key为string序列化 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) // 设置value为json序列化 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(getJackson2JsonRedisSerializer())) // 不缓存空值 .disableCachingNullValues(); Set<String> cacheNames = new HashSet<>(); // 对每个缓存空间应用不同的配置 Map<String, RedisCacheConfiguration> configMap = new HashMap<>(); return RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(defaultCacheConfig) .initialCacheNames(cacheNames) .withInitialCacheConfigurations(configMap) .build(); } /** * 获取Jackson2JsonRedisSerializer序列化对象 * * @return o */ private Jackson2JsonRedisSerializer<Object> getJackson2JsonRedisSerializer() { /* 明文存取 */ Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper(); //指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); jackson2JsonRedisSerializer.setObjectMapper(om); return jackson2JsonRedisSerializer; }}
3、配置yml
3.1、单机配置
spring: redis: # Redis数据库索引(默认为0) database: 0 # 连接地址 host: 127.0.0.1 #端口号 port: 6379 ##连接超时时间 timeout: 3600ms #密码 password: lettuce: pool: # 连接池最大连接数(使用负值表示没有限制) max-active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # 连接池中的最大空闲连接 max-idle: 8 # 连接池中的最小空闲连接 min-idle: 1 #关闭超时 shutdown-timeout: 500ms
3.2、集群配置
spring: redis: cluster: nodes: - 127.0.0.1:7001 - 127.0.0.1:7002 - 127.0.0.1:7003 - 127.0.0.1:7004 - 127.0.0.1:7005 - 127.0.0.1:7006 #连接超时时间 timeout: 3600ms #密码 password: lettuce: pool: # 连接池最大连接数(使用负值表示没有限制) max-active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # 连接池中的最大空闲连接 max-idle: 8 # 连接池中的最小空闲连接 min-idle: 1 #关闭超时 shutdown-timeout: 500ms
4、集成使用
@RestControllerpublic class Controller { @Resource private RedisTemplate redisTemplate; @RequestMapping("redis") public String redis() { // 测试redis String key = "uid"; String value = "测试用户"; // 设置值 redisTemplate.boundValueOps(key).set(value); // 取出值 Object obj = redisTemplate.opsForValue().get(key); System.out.println("取出值为:" + obj); return "操作成功"; }}
5、工具类封装及使用
实际开发中,使用redis的场景会比较多,可以将reidsTemplate的操作封装为工具类,代码如下:
5.1、工具封装
import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.util.CollectionUtils;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.TimeUnit;@Componentpublic class RedisUtils { private static RedisTemplate redisTemplate = null; public RedisUtils(RedisTemplate redisTemplate) { RedisUtils.redisTemplate = redisTemplate; } public static RedisTemplate getRedisTemplate() { return redisTemplate; } /** * 指定缓存失效时间 * * @param key 键 * @param time 时间(秒) * @return */ public static boolean expire(String key, long time, TimeUnit unit) { try { if (time > 0) { redisTemplate.expire(key, time, unit); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据key 获取过期时间 * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public static long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 根据key 获取过期时间 * * @param key 键 不能为null * @return TimeUnit */ public static long getExpire(String key, TimeUnit timeUnit) { return redisTemplate.getExpire(key, timeUnit); } /** * 判断key是否存在 * * @param key 键 * @return true 存在 false不存在 */ public static boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * * @param key 可以传一个值 或多个 */ public static void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } /** * 普通缓存获取 * * @param key 键 * @return 值 */ public static Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * * @param key 键 * @param value 值 * @return true成功 false失败 */ public static boolean set(String key, Object value) { try { redisTemplate.boundValueOps(key).set(value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将值 value 关联到 key ,并将 key 的过期时间设为 timeout * * @param key * @param value * @param timeout 过期时间 * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES * 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS */ public static boolean setEx(String key, Object value, long timeout, TimeUnit unit) { try { set(key, value); if (timeout > 0) { expire(key, timeout, unit); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @return true 成功 false失败 */ public static boolean hset(String key, String item, Object value) { try { redisTemplate.boundHashOps(key).put(item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public static boolean hset(String key, Map<String, String> map) { try { redisTemplate.boundHashOps(key).putAll(map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将值 value 关联到 key ,并将 key 的过期时间设为 timeout * * @param key * @param value * @param timeout 过期时间 * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES * 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS */ public static boolean hSetEx(String key, String item, Object value, long timeout, TimeUnit unit) { try { hset(key, item, value); if (timeout > 0) { expire(key, timeout, unit); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 获取所有给定字段的值 * * @param key * @return */ public static Map<Object, Object> hGetAll(String key) { return redisTemplate.boundHashOps(key).entries(); } /** * 获取所有哈希表中的字段 * * @param key * @return */ public static Set<Object> hKeys(String key) { return redisTemplate.boundHashOps(key).keys(); } /** * 获取哈希表中字段的数量 * * @param key * @return */ public static Long hSize(String key) { return redisTemplate.boundHashOps(key).size(); } /** * 获取哈希表中所有值 * * @param key * @return */ public static List<Object> hValues(String key) { return redisTemplate.boundHashOps(key).values(); } /** * 向一张hash表中读取数据 */ public static Object hget(String key, String item) { try { return redisTemplate.boundHashOps(key).get(item); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 删除hash表中的值 * * @param key 键 不能为null * @param item 项 可以使多个 不能为null */ public static void hdel(String key, Object... item) { redisTemplate.boundHashOps(key).delete(item); } /** * 判断hash表中是否有该项的值 * * @param key 键 不能为null * @param item 项 不能为null * @return true 存在 false不存在 */ public static boolean hHasKey(String key, String item) { return redisTemplate.boundHashOps(key).hasKey(item); } /** * 递增 * * @param key 键 * // * @param by 要增加几(大于0) * @return */ public static long incr(String key, long increment) { if (increment < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.boundValueOps(key).increment(increment); } /** * 为哈希表 key 中的指定字段的整数值加上增量 increment * * @param key * @param field * @param increment * @return */ public static long hIncrBy(String key, Object field, long increment) { if (increment < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.boundHashOps(key).increment(field, increment); }}
5.2、封装使用
通过工具类直接操作Redis
@RestControllerpublic class Controller { @RequestMapping("redis") public String redis() { // 测试redis String key = "uid"; String value = "测试用户"; // 设置值 RedisUtils.set(key, value); // 取出值 Object obj = RedisUtils.get(key); System.out.println("取出值为:" + obj); return "操作成功"; }}