java操作Redis(jedis和lettuce)

一.使用Jedis

1.初始化项目

创建Maven项目并导入jedis依赖和我们需要使用的fastjson依赖

依赖可在Maven仓库中搜索找到:https://search.maven.org/

 1         <!--jedis依赖-->
 2         <dependency>
 3             <groupId>redis.clients</groupId>
 4             <artifactId>jedis</artifactId>
 5             <version>3.2.0</version>
 6         </dependency>
 7         <!--fastjson-->
 8         <dependency>
 9             <groupId>com.alibaba</groupId>
10             <artifactId>fastjson</artifactId>
11             <version>1.2.62</version>
12         </dependency>
依赖

2.编程

1.测试连通

连接远程服务器上的redis时,需要在配置文件中修改为相关配置使得允许远程连接,若需要密码授权也需要进行配置。

运行输出 PONG,表示连通成功。

2.操作redis

jedis操作redis的方法就是redis的原生指令,几乎没有任何改变。

3.事务

 1 package com.kuang;
 2 
 3 import com.alibaba.fastjson.JSONObject;
 4 import redis.clients.jedis.Jedis;
 5 import redis.clients.jedis.Transaction;
 6 
 7 /**
 8  * @Description:
 9  * @author: ZYQ
10  * @date: 2020/10/18 17:18
11  */
12 public class tesetTX {
13     public static void main(String[] args) {
14         Jedis jedis = new Jedis("120.78.198.135", 6379);
15         jedis.auth("dhsqj.1982");
16 
17         JSONObject jsonObject = new JSONObject();
18         jsonObject.put("hello", "world");
19         jsonObject.put("name", "kuangshen");
20         String result = jsonObject.toJSONString();
21 
22         //开启事务
23         Transaction multi = jedis.multi();
24         try {
25             //入队 此时还未执行
26             multi.set("name", result);
27             multi.set("age", result);
28             //执行
29             multi.exec();
30             System.out.println(jedis.get("name"));
31             System.out.println(jedis.get("age"));
32         } catch (Exception e) {
33             multi.discard();
34             e.printStackTrace();
35         } finally {
36             jedis.close();
37         }
38     }
39 }
jedis写事务

二.使用lettuce

1.初始化项目

新建SpringBoot项目,选择redis依赖

1         <dependency>
2             <groupId>org.springframework.boot</groupId>
3             <artifactId>spring-boot-starter-data-redis</artifactId>
4         </dependency>
依赖

2.编写配置文件

在SpringBoot2.x之后,redis依赖的底层实现用lettuce替换掉了jedis

jedis:采用的直连,多个线程操作的话,是不安全的;想要避免不安全,使用jedis pool连接池。更像BIO模式

lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况;可以减少线程数量。更像NIO模式

源码分析:

简单配置一下

spring.redis.host=120.78.198.135
spring.redis.port=6379
spring.redis.password=dhsqj.1982

3.进行测试

 1 package com.example.demo;
 2 
 3 import org.junit.jupiter.api.Test;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.boot.test.context.SpringBootTest;
 6 import org.springframework.data.redis.connection.RedisConnection;
 7 import org.springframework.data.redis.core.RedisTemplate;
 8 
 9 @SpringBootTest
10 class DemoApplicationTests {
11 
12     @Autowired
13     private RedisTemplate redisTemplate;
14 
15     @Test
16     void contextLoads() {
17 
18         /**
19          * 获取redis的连接对象象
20          */
21 //        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
22 //        connection.flushDb();
23 
24         /**
25          * opsForValue 操作String
26          * opsForList 操作list
27          * opsForSet 操作Set
28          * opsForHash 操作Hash
29          * opsForZset 操作Zset
30          * opsForGeo
31          * opsForHyperLogLog
32          */
33         redisTemplate.opsForValue().set("mykey", "kuangshen");
34         System.out.println(redisTemplate.opsForValue().get("mykey"));
35     }
36 
37 }
测试

发现仅在控制台上可以看到正确的结果,而在redis客户端中查看到的序列化之后的结果是这样的

点击redisTemplate查看源码

找到序列化默认的方式为jdk序列化方式,这种方式会将字符进行转义,也就是上上图看到的转义之后的结果

通过redisTemplate上的conditionalOnMissingBean注解,表明我们可以通过自定义redisTemplate。

可以在自定义的redisTemplate中书写序列化方法来覆盖默认的序列化方法,从而解决这个转义问题。

 


 

在未自定义redisTemplate之前,我们再进行测试来加深了解缘由

在pojo包中编写一个最基础的User对象,此时未进行序列化

在测试类中,尝试直接将对象存储在redis中,发现报错,异常说明对象需要序列化

解决方法:在User类中实现序列化接口 Serializable 即可,默认的redisTemplate具有jdk序列化的具体实现,因此在redis中查看到的键值对依然为转义的结果。

 接下来我们尝试将对象转化成json数据格式进行存储并读取

 发现结果如下,因为目前我们还没有覆盖默认的序列化方法

 


 

测试完毕,此时对redisTemplate序列化这方面有了一定的了解。接下来我们去自定义redisTemplate

 1 package com.example.demo.config;
 2 
 3 import com.fasterxml.jackson.annotation.JsonAutoDetect;
 4 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 5 import com.fasterxml.jackson.annotation.PropertyAccessor;
 6 import com.fasterxml.jackson.databind.ObjectMapper;
 7 import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
 8 import org.springframework.context.annotation.Bean;
 9 import org.springframework.context.annotation.Configuration;
10 import org.springframework.data.redis.connection.RedisConnectionFactory;
11 import org.springframework.data.redis.core.RedisTemplate;
12 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
13 import org.springframework.data.redis.serializer.StringRedisSerializer;
14 
15 /**
16  * @Description:
17  * @author: ZYQ
18  * @date: 2020/10/18 22:17
19  */
20 @Configuration
21 public class RedisConfig {
22 
23     @Bean
24     public RedisTemplate<String, Object> template(RedisConnectionFactory factory) {
25         RedisTemplate<String, Object> template = new RedisTemplate<>();
26         template.setConnectionFactory(factory);
27         //配置具体的序列化方法
28         Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
29         ObjectMapper om = new ObjectMapper();
30         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
31         om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
32         jackson2JsonRedisSerializer.setObjectMapper(om);
33 
34         //String的序列化
35         StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
36         //key采用String的序列化方式
37         template.setKeySerializer(stringRedisSerializer);
38         //hash的key也采用String的序列化方式
39         template.setHashKeySerializer(stringRedisSerializer);
40         //value采用jackson序列化方式
41         template.setValueSerializer(jackson2JsonRedisSerializer);
42         //hash的value采用jackson序列化方式
43         template.setHashValueSerializer(jackson2JsonRedisSerializer);
44         template.afterPropertiesSet();
45         return template;
46     }
47 }
自定义redisTemplate

在测试中注入自定义的redisTemplate

    @Autowired
    @Qualifier("template")
    private RedisTemplate redisTemplate;

测试方法

注意:

1.pojo类可以不实现 Serialization 接口,自定义的jackson序列化会帮我们做好

2.pojo类必须有无参构造方法,否则会抛出异常

 运行后可以在redis客户端中发现键值对符合我们的需求了

4.总结

 不管是jedis还是lettuce,其操作方法书写起来都很简单但繁琐,我们可以自己去写一个工具类来包装一下常用的方法,使得代码更简洁。

posted @ 2020-10-18 11:23  缘未到  阅读(2123)  评论(0编辑  收藏  举报