<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Redis的Java客戶端

      Redis 的 Java 客戶端

      • Jedis
        • 優點:以 Redis 命令作為方法名稱,學習成本低廉,簡單且實用
        • 缺點:Jedis 的實例是線程不安全的,在多線程的環境下需要基于線程池來使用
      • lettuce(spring 官方默認)
        • 基于 Netty 實現的,支持同步、異步和響應式編程方式,并且是線程安全的。支持 Redis 的哨兵模式、集群模式、管道模式
      • Redisson(適用于分布式的環境)
        • 基于 Redis 實現的分布式、可伸縮的 Java 數據結構的集合。包含 Map、Queue、Lock、Semaphore、AtomicLong等強大的功能

      Jedis

      Jedis 基本使用步驟

      1. 引入依賴
      2. 創建Jedis對象,建立連接
      3. 使用Jedis,方法名與Redis命令一致
      4. 釋放資源

      測試 Jedis 相關方法

      如果 @BeforeEach報錯,記得在 pom 文件里面引入 Junit API 包的依賴

      <!-- junit-jupiter-api -->
      <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter-api</artifactId>
          <version>5.8.2</version>
          <scope>test</scope>
      </dependency>
      

      (這里以 String 和 Hash 兩種類型為例)

      package com.lcha.test;
      
      import org.junit.jupiter.api.AfterEach;
      import org.junit.jupiter.api.BeforeEach;
      import org.junit.jupiter.api.Test;
      import redis.clients.jedis.Jedis;
      
      import java.util.Map;
      
      public class JedisTest {
      
          private Jedis jedis;
      
          @BeforeEach
          void setUp(){
              //1.建立連接
              jedis = new Jedis("xxxxxxxxxx",6379);
              //2.設置密碼
              jedis.auth("xxxxxxxxx");
              //3.選擇庫
              jedis.select(0);
          }
      
          @Test
          void testStr(){
              //4.存入數據
              String result = jedis.set("name", "胡歌");
              System.out.println("result = " + result);
              //5.獲取數據
              String name = jedis.get("name");
              System.out.println("name = " + name);
          }
      
          @Test
          void testHash(){
              jedis.hset("user:1","name","Jack");
              jedis.hset("user:1","age","21");
      
              Map<String, String> map = jedis.hgetAll("user:1");
              System.out.println(map);
          }
      
          @AfterEach
          void tearDown(){
              //6.釋放連接
              if(jedis != null){
                  jedis.close();
              }
          }
      }
      

      Jedis連接池

      Jedis本身是線程不安全的,并且頻繁的創建和銷毀連接會有性能損耗,因此我們推薦大家使用Jedis連接池代替Jedis的直連方式。

      首先創建一個 Jedis 連接池工具類

      package com.lcha.jedis.util;
      
      import redis.clients.jedis.Jedis;
      import redis.clients.jedis.JedisPool;
      import redis.clients.jedis.JedisPoolConfig;
      
      public class JedisConnectionFactory {
          private static final JedisPool jedisPool;
      
          static {
              //配置連接池
              JedisPoolConfig poolConfig = new JedisPoolConfig();
              poolConfig.setMaxTotal(8);  //最大連接數:8
              poolConfig.setMaxIdle(8);   //最大空閑連接
              poolConfig.setMinIdle(0);
              poolConfig.setMaxWaitMillis(1000);
              //創建連接池對象
              jedisPool = new JedisPool(poolConfig,"xxxx",6379,
                      1000,"xxxx");
          }
      
          public static Jedis getJedis(){
              return jedisPool.getResource();
          }
      }
      

      更改之前 Jedis 的連接方式,采用連接池連接的方式

      package com.lcha.test;
      
      import com.lcha.jedis.util.JedisConnectionFactory;
      import org.junit.jupiter.api.AfterEach;
      import org.junit.jupiter.api.BeforeEach;
      import org.junit.jupiter.api.Test;
      import redis.clients.jedis.Jedis;
      
      import java.util.Map;
      
      public class JedisTest {
      
          private Jedis jedis;
      
          @BeforeEach
          void setUp(){
              //1.建立連接
              //jedis = new Jedis("xxxx",6379);
              jedis = JedisConnectionFactory.getJedis();
              //2.設置密碼
              jedis.auth("xxxx");
              //3.選擇庫
              jedis.select(0);
          }
      
          @Test
          void testStr(){
              //4.存入數據
              String result = jedis.set("name", "胡歌");
              System.out.println("result = " + result);
              //5.獲取數據
              String name = jedis.get("name");
              System.out.println("name = " + name);
          }
      
          @Test
          void testHash(){
              jedis.hset("user:1","name","Jack");
              jedis.hset("user:1","age","21");
      
              Map<String, String> map = jedis.hgetAll("user:1");
              System.out.println(map);
          }
      
          @AfterEach
          void tearDown(){
              if(jedis != null){
                  jedis.close();
              }
          }
      }
      

      注意:當使用連接池連接時,代碼最后的 if(jedis != null){jedis.close();}不會真正的銷毀連接,而是將本連接歸還到連接池中

      源碼如下:

      public void close() {
              if (this.dataSource != null) {
                  Pool<Jedis> pool = this.dataSource;
                  this.dataSource = null;
                  if (this.isBroken()) {
                      pool.returnBrokenResource(this);
                  } else {
                      pool.returnResource(this); //注意這里!!!!
                  }
              } else {
                  this.connection.close();
              }
      
          }
      

      SpringDataRedis

      SpringData是Spring中數據操作的模塊,包含對各種數據庫的集成,其中對Redis的集成模塊就叫做SpringDataRedis

      官網地址:https://spring.io/projects/spring-data-redis

      • 提供了對不同Redis客戶端的整合(Lettuce和Jedis)
      • 提供了RedisTemplate統一API來操作Redis
      • 支持Redis的發布訂閱模型
      • 支持Redis哨兵和Redis集群
      • 支持基于Lettuce的響應式編程
      • 支持基于JDK、JSON、字符串、Spring對象的數據序列化及反序列化
      • 支持基于Redis的JDKCollection實現

      RedisTemplate 工具類

      API 返回值類型 說明
      RedisTemplate.opsForValue() ValueOperations 操作 String 類型數據
      RedisTemplate.opsForHash() HashOperations 操作 Hash 類型數據
      RedisTemplate.opsForList() ListOperations 操作 List 類型數據
      RedisTemplate.opsForSet() SetOperations 操作 Set 類型數據
      RedisTemplate.opsForZSet() ZSetOperations 操作 SortedSort 類型數據
      RedisTemplate 通用命令

      使用步驟

      1. 引入 spring-boot-starter-data-redis 依賴

        <!-- redis依賴 -->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-data-redis</artifactId>
                </dependency>
                <!-- common-pool -->
                <dependency>
                    <groupId>org.apache.commons</groupId>
                    <artifactId>commons-pool2</artifactId>
                </dependency>
        
      2. 在 application.yml 文件中配置 Redis 信息

        spring:
          redis:
            host: xxxx
            port: 6379
            password: xxxx
            lettuce:
              pool:
                max-active: 8
                max-idle: 8
                min-idle: 0
                max-wait: 100ms
        
      3. 注入 RedisTemplate 并使用

      package com.lcha;
      
      import org.junit.jupiter.api.Test;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      import org.springframework.data.redis.core.RedisTemplate;
      
      @SpringBootTest
      class RedisDemoApplicationTests {
      
          @Autowired
          private RedisTemplate redisTemplate;
      
          @Test
          void testString() {
              //寫入一條String數據
              redisTemplate.opsForValue().set("name", "胡歌");
              //獲取string數據
              Object name = redisTemplate.opsForValue().get("name");
              System.out.println("name = " + name);
          }
      
      }
      

      序列化問題

      RedisTemplate可以接收任意Object作為值寫入Redis,只不過寫入前會把Object序列化為字節形式,默認是采用JDK序列化,得到的結果是這樣的:

      缺點:

      1. 可讀性差
      2. 內存占用較大

      解決方法:改變序列化器

      自定義 RedisTemplate 序列化方式

      package com.lcha.redis.config;
      
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.data.redis.connection.RedisConnectionFactory;
      import org.springframework.data.redis.core.RedisTemplate;
      import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
      import org.springframework.data.redis.serializer.RedisSerializer;
      import org.springframework.data.redis.serializer.StringRedisSerializer;
      
      @Configuration
      public class RedisConfig {
      
          @Bean
          public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
              //創建 RedisTemplate 對象
              RedisTemplate<String, Object> template = new RedisTemplate<>();
              //設置連接工廠
              template.setConnectionFactory(connectionFactory);
              //創建 JSON 序列化工具
              GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
              //設置 Key 的序列化
              template.setKeySerializer(RedisSerializer.string());
              template.setHashKeySerializer(RedisSerializer.string());
              //設置 Value 的序列化
              template.setValueSerializer(jsonRedisSerializer);
              template.setHashValueSerializer(jsonRedisSerializer);
              //返回
              return template;
          }
      }
      

      重新運行剛才的代碼,結果如下圖所示:

      存儲對象數據時也是一樣的

      1. 創建一個對象類

        package com.lcha.redis.pojo;
        
        import lombok.AllArgsConstructor;
        import lombok.Data;
        import lombok.NoArgsConstructor;
        
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public class User {
            private String name;
            private Integer age;
        }
        
      2. 編寫測試方法

      3. 	@Test
            void testSaveUser(){
                redisTemplate.opsForValue().set("user:100", new User("胡歌",21));
                User o = (User) redisTemplate.opsForValue().get("user:100");
                System.out.println("o = " + o);
            }
        
      4. 打印結果

      JSON方式依然存在的缺陷

      盡管 JSON 的序列化方式可以滿足我們的需求,但是依然存在一些問題。

      為了在反序列化時知道對象的類型,JSON序列化器會將類的class類型寫入json結果中,存入Redis,會帶來額外的內存開銷。

      如何解決

      為了節省內存空間,我們并不會使用JSON序列化器來處理value,而是統一使用String序列化器,要求只能存儲String類型的key和value。當需要存儲Java對象時,手動完成對象的序列化和反序列化。

      1. 直接使用 StringRedisTemplate 即可

        package com.lcha;
        
        import com.fasterxml.jackson.core.JsonProcessingException;
        import com.fasterxml.jackson.databind.ObjectMapper;
        import com.lcha.redis.pojo.User;
        import org.junit.jupiter.api.Test;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.test.context.SpringBootTest;
        import org.springframework.data.redis.core.RedisTemplate;
        import org.springframework.data.redis.core.StringRedisTemplate;
        
        @SpringBootTest
        class RedisStringTests {
        
            @Autowired
            private StringRedisTemplate stringRedisTemplate;
        
            @Test
            void testString() {
                //寫入一條String數據
                stringRedisTemplate.opsForValue().set("name", "胡歌");
                //獲取string數據
                Object name = stringRedisTemplate.opsForValue().get("name");
                System.out.println("name = " + name);
            }
        
            private static final ObjectMapper mapper = new ObjectMapper();
        
            @Test
            void testSaveUser() throws JsonProcessingException {
                //創建對象
                User user = new User("虎哥",21);
                //手動序列化
                String json = mapper.writeValueAsString(user);
                //寫入數據
                stringRedisTemplate.opsForValue().set("user:200", json);
                //獲取數據
                String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
                User user1 = mapper.readValue(jsonUser, User.class);
                System.out.println("user1 = " + user1);
            }
        
        }
        
      2. 結果如下

      對 Hash 類型的操作

      1. 編寫方法

        @Test
            void testHash(){
                stringRedisTemplate.opsForHash().put("user:300", "name", "張三");
                stringRedisTemplate.opsForHash().put("user:300", "age", "18");
        
                Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:300");
                System.out.println("entries = " + entries);
        
            }
        
      2. 結果如下

      posted @ 2022-05-30 18:55  染沁  閱讀(671)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品一级久久黄色片| 少妇人妻偷人精品系列| 国产a在视频线精品视频下载| 巨熟乳波霸若妻在线播放| 国产精品大片中文字幕| 欧美黑人又粗又大又爽免费| 中文字幕日韩国产精品| 中文人妻| 2020精品自拍视频曝光| 国产三级黄色片在线观看| 色窝窝免费一区二区三区| 久久av无码精品人妻出轨| 久久综合偷拍视频五月天| 一本一本久久a久久综合精品| 国产真人无遮挡免费视频 | 蜜臀av无码一区二区三区| 88国产精品视频一区二区三区| 大地资源高清免费观看| 国产在线观看网址不卡一区| 欧美成人一卡二卡三卡四卡| 久久a级片| 欧美一本大道香蕉综合视频| 尼勒克县| 久久夜色国产噜噜亚洲av| 玩弄漂亮少妇高潮白浆| 热re99久久精品国产99热| 国产老肥熟一区二区三区| 蜜臀av久久国产午夜| 五月婷婷久久草| 人妻丰满熟妇av无码处处不卡| 国产线播放免费人成视频播放| 四虎永久精品免费视频| 欧美老少配性行为| 一区二区三区午夜无码视频| 中文字幕久久精品波多野结| 熟女在线视频一区二区三区| 思思久99久女女精品| 亚洲精品岛国片在线观看| 国产精品久久自在自线不卡| 熟妇无码熟妇毛片| 亚洲免费视频一区二区三区|