欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Redis学习:SpringBoot整合Redis

时间:2023-07-03

jedis是Redis推荐的Java连接Redis客户端,但是实际上springboot2推荐的是连接Redis客户端是lettuce (实际上对应比较流行的客户端还有一个redisson),主要是jedis好久不更新对新的功能支持没有另外的好(本身Springboot2的选择也是一个侧面说明,关键是lettuce是线程安全的,jedis不是。)

一 先来个jedis的简单demo

pom文件配置

redis.clients jedis 3.2.0 com.alibaba fastjson 1.2.70

测试代码

public class TestPing { public static void main(String[] args) { Jedis jedis = new Jedis("192.168.XX.XX", 17006); jedis.auth("XXXXXX"); String response = jedis.ping(); System.out.println(response); // PONG }}

二 springboot整合Redis

初始化项目,除了我们常勾选的web,还要注意勾选NoSQL的Redis

我们不是说lettuce代替jedis了吗,怎么看?可以去pom文件找springboot 的redis配置,如图,点击过去

会展示如下:

再说一下两者区别差异:
jedis:采用的直连,多个线程操作的话,是不安全的。如果要避免不安全,使用jedis pool连接池!更像BIO模式(同步阻塞的)
lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式(同步非阻塞的)

一 RedisAutoConfiguratio

RedisAutoConfiguratio是springdata的redis自动配置类。

// IntelliJ API Decompiler stub source generated from a class file // Implementation of methods is not availablepackage org.springframework.boot.autoconfigure.data.redis;@org.springframework.context.annotation.Configuration(proxyBeanMethods = false)@org.springframework.boot.autoconfigure.condition.ConditionalOnClass({org.springframework.data.redis.core.RedisOperations.class})@org.springframework.boot.context.properties.EnableConfigurationProperties({org.springframework.boot.autoconfigure.data.redis.RedisProperties.class})@org.springframework.context.annotation.import({org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration.class, org.springframework.boot.autoconfigure.data.redis.JedisConnectionConfiguration.class})public class RedisAutoConfiguration { public RedisAutoConfiguration() { } @org.springframework.context.annotation.Bean @org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean(name = {"redisTemplate"}) @org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate(org.springframework.data.redis.connection.RedisConnectionFactory.class) public org.springframework.data.redis.core.RedisTemplate redisTemplate(org.springframework.data.redis.connection.RedisConnectionFactory redisConnectionFactory) { } @org.springframework.context.annotation.Bean @org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean @org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate(org.springframework.data.redis.connection.RedisConnectionFactory.class) public org.springframework.data.redis.core.StringRedisTemplate stringRedisTemplate(org.springframework.data.redis.connection.RedisConnectionFactory redisConnectionFactory) { }}

只有两个Bean:

RedisTemplate 默认的template,你也可以重写一个这个StringRedisTemplate 针对String使用的频率比较高的tempalte

在RedisTemplate上也有一个条件注解,说明我们是可以对其进行定制化的

开始测试
(一)配置文件

# 配置redisspring.redis.host=192.168.XX.XXspring.redis.port=XXXX# Redis服务器连接密码(默认为空)spring.redis.password=XXXX

(二)测试demo

@SpringBootTestclass ZpRedis2ApplicationTests { @Resource private RedisTemplate redisTemplate; @Test void contextLoads() { // redisTemplate 操作不同的数据类型,api和我们的指令是一样的 // opsForValue 操作字符串 类似String // opsForList 操作List 类似List // opsForHah // 除了基本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务和基本的CRUD // 获取连接对象 //RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); //connection.flushDb(); //connection.flushAll(); redisTemplate.opsForValue().set("mykey111","zhangpeng"); System.out.println(redisTemplate.opsForValue().get("mykey111")); System.out.println(redisTemplate.opsForValue().get("mykey111")); }}

运行查看测试结果

三 自定义RedisTemplate
从上面截图我们可以看到,vlaue值跟我们输入的有一些出入,实际上就是序列化的问题,我们可以把Object转换成String挥着JSON来解决。这就需要我们自定义RedisTemplate。

(一)配置RedisTemplate

@Configuration//这里的Configuration 可以看做我们最开始学习spring的配置文件。其他文件可以通过@Qualifier指定注入的bean使用public class RedisConfig { @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { // 将template 泛型设置为 RedisTemplate template = new RedisTemplate(); // 连接工厂,不必修改 template.setConnectionFactory(redisConnectionFactory); // key、hash的key 采用 String序列化方式 template.setKeySerializer(RedisSerializer.string()); template.setHashKeySerializer(RedisSerializer.string()); // value、hash的value 采用 Jackson 序列化方式 template.setValueSerializer(RedisSerializer.json()); template.setHashValueSerializer(RedisSerializer.json()); template.afterPropertiesSet(); return template; }}

(2)redis操作代码修改
由于重新定义RedisTemplate,我们在使用的同时也要注意引入我们自定义的RedisTemplate,代码的关于RedisTemplate引入要做修改,新的测试代码如下:

@SpringBootTestclass ZpRedis2ApplicationTests {// @Resource// private RedisTemplate redisTemplate; @Autowired //这里通过@qualifier 来指定注入的bean @Qualifier("redisTemplate") private RedisTemplate redisTemplate;// RedisTemplate redisTemplate; @Test void contextLoads() { // redisTemplate 操作不同的数据类型,api和我们的指令是一样的 // opsForValue 操作字符串 类似String // opsForList 操作List 类似List // opsForHah // 除了基本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务和基本的CRUD // 获取连接对象 //RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); //connection.flushDb(); //connection.flushAll(); redisTemplate.opsForValue().set("mykey112","zhangpeng111"); System.out.println(redisTemplate.opsForValue().get("mykey112")); System.out.println(redisTemplate.opsForValue().get("mykey112")); }}

(三)查看结果

Redis工具类

package com.example.zp_redis_2.util;import org.springframework.beans.factory.annotation.Autowired;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 final class RedisUtil { @Autowired private RedisTemplate redisTemplate; // =============================common============================ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } // ============================String============================= public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return 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; } } public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递增因子必须大于"); } return redisTemplate.opsForValue().increment(key, delta); } public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递减因子必须大于"); } return redisTemplate.opsForValue().increment(key, -delta); } // ================================Map================================= public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } public Map hmget(String key) { return redisTemplate.opsForHash().entries(key); } public boolean hmset(String key, Map map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean hmset(String key, Map map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean hset(String key, String item, Object value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } public void hdel(String key, Object..、item) { redisTemplate.opsForHash().delete(key, item); } public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } // ============================set============================= public Set sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } public boolean sHasKey(String key, Object value) { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { e.printStackTrace(); return false; } } public long sSet(String key, Object..、values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } public long sSetAndTime(String key, long time, Object..、values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) { expire(key, time); } return count; } catch (Exception e) { e.printStackTrace(); return 0; } } public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } public long setRemove(String key, Object..、values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } // ===============================list================================= public List lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { e.printStackTrace(); return null; } } public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean lSet(String key, List value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean lSet(String key, List value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } }}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。