hincky的主页 hincky的主页
  • 学习笔记

    • Vue笔记
    • Vuepress
    • nginx
  • 语言类

    • java
    • go
    • python
    • 设计模式
  • 框架类

    • Spring
    • Spring Security
    • Mybatis
  • 容器技术

    • docker
    • k8s
    • helm
    • prometheus
    • grafana
    • jenkins
  • 命令集合

    • linux命令
    • docker命令
    • git命令
    • vim命令
    • k8s命令
  • 数据库

    • sql
    • mysql
  • 协议

    • 网络模型
    • http/1.1
    • WebSocket
    • http/2
    • TLS/SSL
    • tcp
    • IP
    • tcpdump抓包命令
    • wireshark抓包工具
  • 通用

    • Git
  • 技术分享

    • git push/pull总是超时怎么办
    • idea debug技巧
    • postman使用
    • 问题总结
    • idea使用技巧
  • Oauth2

    • Oauth2原理
  • 项目列表

    • redis项目
    • 微服务项目
  • 分类
  • 标签
  • 归档
  • 随笔
GitHub (opens new window)

Hincky

当有趣的人,做想做的事
  • 学习笔记

    • Vue笔记
    • Vuepress
    • nginx
  • 语言类

    • java
    • go
    • python
    • 设计模式
  • 框架类

    • Spring
    • Spring Security
    • Mybatis
  • 容器技术

    • docker
    • k8s
    • helm
    • prometheus
    • grafana
    • jenkins
  • 命令集合

    • linux命令
    • docker命令
    • git命令
    • vim命令
    • k8s命令
  • 数据库

    • sql
    • mysql
  • 协议

    • 网络模型
    • http/1.1
    • WebSocket
    • http/2
    • TLS/SSL
    • tcp
    • IP
    • tcpdump抓包命令
    • wireshark抓包工具
  • 通用

    • Git
  • 技术分享

    • git push/pull总是超时怎么办
    • idea debug技巧
    • postman使用
    • 问题总结
    • idea使用技巧
  • Oauth2

    • Oauth2原理
  • 项目列表

    • redis项目
    • 微服务项目
  • 分类
  • 标签
  • 归档
  • 随笔
GitHub (opens new window)
  • redis-点评项目

    • 基础篇

      • 安装redis
        • 认识Redis
        • 安装Redis
          • 依赖库
          • 下载安装包并解压
          • 启动
          • 默认启动
          • 指定配置启动
          • 开机自启
        • Redis桌面客户端
          • 命令行客户端
          • 图形化桌面客户端
          • 安装
          • 建立连接
          • 编程客户端
      • redis常见命令以及数据类型
        • Redis通用命令
        • String类型
          • String的常见命令
          • Key结构
        • Hash类型
        • List类型
        • Set类型
        • SortedSet类型
      • redis的java客户端
        • Redis客户端种类
          • Jedis
          • SpringDataRedis]
      • Jedis客户端
        • SpringDataRedis客户端
          • 快速入门
            • 1)引入依赖
            • 2)配置Redis
            • 3)注入RedisTemplate
            • 4)编写测试
            • 快速入门总结
          • 注意项
            • 默认序列化的弊端
            • 自定义序列化
            • StringRedisTemplate
          • 总结:
          • Hash结构操作
      • 实战篇

      • 高级篇

    • springcloud微服务项目

    • 项目实战
    • redis-点评项目
    • 基础篇
    hincky
    2022-11-06
    目录

    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实现

    SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

    # 快速入门

    SpringBoot已经提供了对SpringDataRedis的支持,使用非常简单。

    首先,新建一个maven项目,然后按照下面步骤执行:

    # 1)引入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.5.7</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.heima</groupId>
        <artifactId>redis-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>redis-demo</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <!--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>
            <!--Jackson依赖-->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <excludes>
                            <exclude>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                            </exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64

    # 2)配置Redis

    spring:
      redis:
        host: 192.168.150.101 #改成你自己的ip
        port: 6379
        password: 123321
        lettuce:
          pool:
            max-active: 8  #最大连接
            max-idle: 8   #最大空闲连接
            min-idle: 0   #最小空闲连接
            max-wait: 1000ms #连接等待时间
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 3)注入RedisTemplate

    编写Test测试类,就是直接在test文件夹下的java.com.xxx.xxApplicationTest里面写

    因为有了SpringBoot的自动装配,我们可以拿来就用:

    @Autowired
    private RedisTemplate redisTemplate;
    
    1
    2

    # 4)编写测试

    @SpringBootTest
    class RedisStringTests {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        @Test
        void testString() {
            // 写入一条String数据
            redisTemplate.opsForValue().set("name", "虎哥");
            // 获取string数据
            Object name = stringRedisTemplate.opsForValue().get("name");
            System.out.println("name = " + name);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    # 快速入门总结

    贴心小提示:SpringDataJpa使用起来非常简单,记住如下几个步骤即可

    SpringDataRedis的使用步骤:

    • 引入spring-boot-starter-data-redis依赖
    • 在application.yml配置Redis信息
    • 注入RedisTemplate到IoC容器中
    • 通过RedisTemplate来set赋值,get取值

    # 注意项

    使用SpringDataRedis,最终还是通过RedisTemplate来与Redis进行交互

    RedisTemplate可以接收任意类型的对象

    提示

    原理就是将Object转成Redis可以接收的字节,因此set所存入的key和value都被当成java对象了

    RedisTemplate底层将这些对像,利用JDK的序列化器进行序列化或反序列化进行存储或读取。

    # 默认序列化的弊端

    写入Redis之前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:

    警告

    缺点:

    • 可读性差 不能所见即所得
    • 内存占用较大 序列化后又臭又长

    # 自定义序列化

    既然默认RedisTemplate的序列化方式如此不好

    我们可以自定义RedisTemplate的序列化方式,代码如下:

    @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
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    这里采用了JSON序列化来代替默认的JDK序列化方式。最终结果如图:

    整体可读性有了很大提升,并且能将Java对象自动的序列化为JSON字符串,并且查询时能自动把JSON反序列化为Java对象。不过,其中记录了序列化时对应的class名称,目的是为了查询时实现自动反序列化。

    警告

    为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销。

    # StringRedisTemplate

    尽管JSON的序列化方式可以满足我们的需求,但依然存在一些问题,如图:

    1653054602930

    为了节省内存空间,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。

    因为存入和读取时的序列化及反序列化都是我们自己实现的,SpringDataRedis就不会将class信息写入Redis了。

    这种用法比较普遍,因此SpringDataRedis就提供了RedisTemplate的子类:StringRedisTemplate,它的key和value的序列化方式默认就是String方式。

    省去了我们自定义RedisTemplate的序列化方式的步骤,而是直接使用:

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // JSON序列化工具
    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);
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    此时我们再来看一看存储的数据,小伙伴们就会发现那个class数据已经不在了,节约了我们的空间~

    1653054945211

    # 总结:

    RedisTemplate的两种序列化实践方案:

    • 方案一:

      • 自定义RedisTemplate
        • 可读性差
        • 内存占用大
      • 修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer
        • 为了自动反序列化,JSON序列化器会将类的class类型写入json结果中
        • 给Redis带来额外的内存开销
    • 方案二:

      • 使用StringRedisTemplate
        • 写入Redis时,手动把对象序列化为JSON
        • 读取Redis时,手动把读取到的JSON反序列化为对象

    # Hash结构操作

    hash操作就是一个key可以对应多个字段的值。

    在基础篇的最后,咱们对Hash结构操作一下,收一个小尾巴,这个代码咱们就不再解释啦

    @SpringBootTest
    class RedisStringTests {
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        @Test
        void testHash() {
            stringRedisTemplate.opsForHash().put("user:400", "name", "虎哥");
            stringRedisTemplate.opsForHash().put("user:400", "age", "21");
    
            Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:400");
            System.out.println("entries = " + entries);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    马上就开始新的篇章~~~进入到我们的Redis实战篇

    编辑 (opens new window)
    #redis
    Jedis客户端
    导读

    ← Jedis客户端 导读→

    最近更新
    01
    人生前期重要的能力
    05-17
    02
    防火墙命令
    04-11
    03
    docker-compose部署mysql主从集群
    03-22
    更多文章>
    Theme by Vdoing | Copyright © 2022-2023 Hincky | MIT License | 粤ICP备2022120427号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式