zoukankan      html  css  js  c++  java
  • 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,其操作方法书写起来都很简单但繁琐,我们可以自己去写一个工具类来包装一下常用的方法,使得代码更简洁。

  • 相关阅读:
    终于等到你---订餐系统之负载均衡(nginx+memcached+ftp上传图片+iis)
    订餐系统之同步饿了么商家订单
    订餐系统之同步口碑外卖商家菜单与点点送订单
    基于SuperSocket的IIS主动推送消息给android客户端
    基于mina框架的GPS设备与服务器之间的交互
    订餐系统之微信支付,踩了官方demo的坑
    订餐系统之自动确认淘点点订单
    订餐系统之Excel批量导入
    移除首页->重回首页
    订餐系统之获取淘宝外卖订单
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/13834216.html
Copyright © 2011-2022 走看看