Redis 学习笔记Jedis & Lettuce
Posted Adorable_Rocy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 学习笔记Jedis & Lettuce相关的知识,希望对你有一定的参考价值。
前言:Jedis是之前被推荐的最为广泛的操作Redis的客户端连接开发工具,现在被lettuce代替了,我们简单了解一下这个的使用吧。
1.导入Jedis依赖
1.jedis坐标如下
<dependencies>
<!-- 导入jedis-->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 导入fastjson-->
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
</dependencies>
2.Java端测试连接
public class TestPing {
public static void main(String[] args) {
//new 一个Jedis对象即可
Jedis jedis = new Jedis("127.0.0.1",6379);
// 返回PING代表连接成功
System.out.println(jedis.ping());
//关机连接
jedis.close();
}
}
3.使用Jedis开启事务
public class TestTX {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
JSONObject jsonObject = new JSONObject();
jsonObject.put("name","zhangsan");
jsonObject.put("age","18");
String s = jsonObject.toString();
//开启事务
Transaction multi = jedis.multi();
try {
multi.set("user1",s);
multi.set("user2",s);
//执行事务
multi.exec();
} catch (Exception e) {
//放弃事务
multi.discard();
e.printStackTrace();
}finally {
System.out.println(jedis.get("user1"));
System.out.println(jedis.get("user2"));
//关闭连接
jedis.close();
}
}
}
2.SpringBoot整合Redis
- 导入基本坐标:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 说明:在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce
- jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全,使用jedis pool连接池。BIO模式
- lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况。可以减少线程数量,更像NIO模式
redis自动配置类分析
1.自动配置类,专门提取了一个操作String字符串的实例(StringRedisTemplate)
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")//在没有redisTemplate这个bean时才生效,这样我们可以自定义一个RedisTemple来替换。
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//默认的RedisTemplate没有过多的设置,redis对象都是需要序列化。(尤其是使用了netty这种异步通信,默认使用jdk序列化)
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
2.配置
spring:
redis:
host: 192.168.242.132 //虚拟机的ip
port: 6379
3.测试
@Test
void contextLoads() {
redisTemplate.opsForValue().set("name","zhangsan");
System.out.println(redisTemplate.opsForValue().get("name"));
}
############控制台###############
zhangsan
3.关于Redis序列化问题
1.准备一个对象
@Component
@NoArgsConstructor
@AllArgsConstructor
@Data
public class User{
private String name;
private int age;
}
2.测试添加到redis中
@Autowired
private RedisTemplate redisTemplate;
@Test
void test() {
//真实的开发一般都是使用json来传递对象
User user = new User("张三", 3);
redisTemplate.opsForValue().set("user", user);
System.out.println(redisTemplate.opsForValue().get("user"));
}
异常抛出:(形成的原因就是实体类未实现序列化接口 Serializable)
org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is org.springframework.core.NestedIOException: Failed to deserialize object type; nested exception is java.lang.ClassNotFoundException: com.zzgele.qmkx.info.enums.InfomationTypeEnum
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:84) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at org.springframework.data.redis.serializer.SerializationUtils.deserializeValues(SerializationUtils.java:54) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at org.springframework.data.redis.serializer.SerializationUtils.deserialize(SerializationUtils.java:68) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at org.springframework.data.redis.core.AbstractOperations.deserializeValues(AbstractOperations.java:268) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at org.springframework.data.redis.core.DefaultListOperations.lambda$range$6(DefaultListOperations.java:171) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at org.springframework.data.redis.core.DefaultListOperations.range(DefaultListOperations.java:171) ~[spring-data-redis-2.0.7.RELEASE.jar!/:2.0.7.RELEASE]
at com.zzgele.qmkx.info.service.impl.InfomationServiceImpl.refreshInfo(InfomationServiceImpl.java:1116) ~[classes!/:0.0.1-SNAPSHOT]
3.添加到redis中数据被转义,形成了一堆看不懂的东西
4.追加到RedisTemplate中的序列化方式
5.默认实现(JDK序列化)
if (this.defaultSerializer == null) {
this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
}
if (this.enableDefaultSerializer) {
if (this.keySerializer == null) {
this.keySerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.valueSerializer == null) {
this.valueSerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.hashKeySerializer == null) {
this.hashKeySerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.hashValueSerializer == null) {
this.hashValueSerializer = this.defaultSerializer;
defaultUsed = true;
}
6.如何修改默认序列化方式?
- 在其中提供了setKeySerializer方法,参数只需要传入序列化方式即可。
补充:RedisSerializer是个接口,里面提供多种方式,这里我们使用常用的Jackson序列化方式
7.修改Redis序列化的模板如下:
@Configuration
public class RedisConfig {
//编写自定义的RedisTemplate
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
//设置Redis连接工厂
template.setConnectionFactory(redisConnectionFactory);
//Json序列化配置
//传入Object对象
Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jsonRedisSerializer.setObjectMapper(objectMapper);
//String 序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key 采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key 采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value 采用json的序列化方式
template.setValueSerializer(jsonRedisSerializer);
//hash的value 采用json的序列化方式
template.setHashValueSerializer(jsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
8.再次查看redis中存入的数据
127.0.0.1:6379> keys *
1) "user"
127.0.0.1:6379>
序列化完成
以上是关于Redis 学习笔记Jedis & Lettuce的主要内容,如果未能解决你的问题,请参考以下文章