Redis概述及安装

Redis是什么

基于内存的key-value结构的非关系型数据库,远程字典服务

特点

基于内存存储,读写性能高

适合存储热点数据(热点商品,资讯,新闻)

使用范围广

能做什么

  • 数据缓存
  • 消息队列
  • 注册中心
  • 发布订阅

Redis入门

官网:https://redis.io

关系型数据库(RDBMS):

  • Mysql
  • Oracle
  • DB2
  • SQLServer

非关系型数据库(NoSql):

  • Redis
  • Mongo db
  • MemCached

下载与安装

Redis安装包分为windows版和Linux版:

下载后得到下面安装包:

image-20230718120421604

在Linux系统安装Redis步骤:

  1. 将Redis安装包上传到Linux到soft目录

  2. 解压安装包,命令:tar -xvf redis-4.0.0.tar.gz -C /usr/local

  3. 安装Redis的依赖环境gcc,命令:yum install gcc-c++

  4. 进入/usr/local/redis-4.0.0,进行编译,命令:make

  5. 进入redis的src目录进行安装,命令:make install

  6. 进入/usr/local/redis-4.0.0 ,把redis.conf文件拷贝到src目录中 cp redis.conf src

  7. 修改redis.conf文件,需要修改的地方有:

    1. 修改redis.conf文件,让其在后台启动不要霸屏的方式启动, 将配置文件中的daemonize配置项改为yes,默认值为no。

    2. reids默认是没有密码的,如果你需要有密码,将配置文件中的 # requirepass foobared 配置项取消注释,默认为注释状态。foobared为密码,可以根据情况自己指定。(选做)

    3. redis的服务默认只是允许本机连接,其他机器默认情况是不被允许连接,如果允许其他机器也能连接linux的reids服务,注释掉 bind 127.0.0.1

      protected-mode yes改成no 关闭保护模式

    4. 如果redis服务是后台启动 我们的关闭redis服务如下:

      在src目录下 ./redis-cli shutdown

      启动redis服务 在src目录下

      ./redis-server redis.conf

  8. 启动redis的服务, 使用 redis-server redis.conf

  9. 启动客户端去连接服务端测试: 启动客户端的方式:

    1. 方式一(没有密码方式): 在src目录中 ./redis-cli

image-20230718120446561

  1. 方式二(如果存在密码情况): 在src目录中: ./redis-cli -h 127.0.0.1 -p 端口号 -a 密码

image-20230718120459517

启动和停止Redis

执行Redis服务启动脚本文件redis-server

通过启动日志可以看到,Redis默认端口号为6379

Ctrl + C停止Redis服务

通过redis-cli可以连接到本地的Redis服务,默认情况下不需要认证即可连接成功。

退出客户端可以输入exit或者quit命令。

在Java中操作Redis

Redis 的 Java 客户端很多,官方推荐的有三种:

  • Jedis
  • Lettuce
  • Redisson

Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis。

Jedis

Jedis 是 Redis 的 Java 版本的客户端实现。

maven坐标:

 <dependencies>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.8.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

使用 Jedis 操作 Redis 的步骤:

  1. 获取连接
  2. 执行操作
  3. 关闭连接

示例代码:

package com.tyhxzy.test;

import org.junit.Test;
import redis.clients.jedis.Jedis;

public class AppTest {


    @Test
    public void test01(){
        //1. 创建Jedis连接Redis
        Jedis jedis = new Jedis("192.168.174.128",6379);
        //2. 操作
        jedis.set("name","张三");
        //3. 关闭连接
        jedis.close();
    }

}

Spring Data Redis

介绍

Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。

网址:https://spring.io/projects/spring-data-redis

maven坐标:

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
	<version>2.4.8</version>
</dependency>

Spring Boot提供了对应的Starter,maven坐标:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对 Jedis 客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

  • ValueOperations:简单K-V操作
  • SetOperations:set类型数据操作
  • ZSetOperations:zset类型数据操作
  • HashOperations:针对hash类型的数据操作
  • ListOperations:针对list类型的数据操作

使用方式

环境搭建

第一步:创建maven项目springdataredis_demo,配置pom.xml文件

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
    </parent>
    
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
     
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>
   

第二步:编写启动类

package com.tyhxzy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class,args);
    }

}

第三步:配置application.yml

spring:
  redis:
    host: 192.168.206.128
    port: 6379
    #    password:  有密码你才写
    database: 0 #redis默认有16个数据库, 操作的数据库是哪个
    jedis:
      pool:
        max-active: 10 #最大链接数,连接池中最多有10个
        max-idle: 5   # 最大空闲数
        min-idle: 1   #最小空闲数
        #举个例子: 连接池初始化3个链接, 客户拿走2个链接,空闲1个,达到最小的空闲数,必须马上增加
        max-wait: 1ms #连接池最大阻塞等待时间

解释说明:

spring.redis.database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个数据库,编号分别是从0到15。

可以通过修改Redis配置文件来指定数据库的数量。

第四步:

springdata_redis默认帮我们创建的RedisTemplate对象是使用jdk的序列号器帮我们键与值存储到redis中,而jdk的序列号器对键与值是采用二进制的方式存储的,所以我们会看到乱码的情况。如果我们需要看得懂,那么需要修改redistemplate使用的序列号器才行。 提供配置类

package com.tyhxzy.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.StringRedisSerializer;

@Configuration
public class MyRedisAutoConfig {


    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer()); //key的序列号器
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); //值序列号器
        return template;
    }
}

添加依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tyhxzy</groupId>
    <artifactId>springdataredis_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.11.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.11.1</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.4.5</version>
            </plugin>
        </plugins>
    </build>
</project>

解释说明:

当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate 对象,但是默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别

第五步:提供测试类

package com.tyhxzy.test;

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.*;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@SpringBootTest
public class RedisTemplateTest {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

   

}

操作字符串类型数据
package com.tyhxzy.test;

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.*;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@SpringBootTest
public class RedisTemplateTest {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 操作字符串类型
     */
    @Test
    public void testStr(){
        //1. 得到操作字符串类型的对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //2. 操作字符串
        //存储
        valueOperations.set("name","狗娃");


        //获取
        System.out.println("获取到的值:"+ valueOperations.get("name"));
        //设置过期时间
        valueOperations.set("age","18",1, TimeUnit.MINUTES); //设置过期时间为一分钟

        //如果不存在key则添加,则则不添加
        valueOperations.setIfAbsent("name","狗剩");
    }

    /**
     * 操作hash类型
     */
    @Test
    public void testHash(){
        //1. 得到操作hash类型的客户端对象
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        //存储
        hashOperations.put("person","id","110");
        hashOperations.put("person","name","狗娃");
        //取
        System.out.println("姓名:"+ hashOperations.get("person","name"));
        //所有field
        Set<Object> set = hashOperations.keys("person");
        for (Object key : set) {
            System.out.print(key+",");
        }
        System.out.println();

        //所有值
        List<Object> list = hashOperations.values("person");
        for (Object value : list) {
            System.out.print(value+",");
        }
        System.out.println();
    }



   

}

操作哈希类型数据
  @Test
    public void testHash(){
        //1. 得到哈希客户端
        HashOperations hashOperations = redisTemplate.opsForHash();
        //2. 操作
        hashOperations.put("p1","id","110");
        hashOperations.put("p1","name","邓天阳");
        hashOperations.put("p1","age",28);

        //获取
        System.out.println("天阳年龄:"+hashOperations.get("p1","age"));

        //获取所有field
        Set set = hashOperations.keys("p1");
        set.forEach(System.out::println);


        List list = hashOperations.values("p1");
        for (Object item : list) {
            System.out.print(item+",");
        }
操作列表类型数据
/**
     * 操作list类型
     */
    @Test
    public void testList(){
        //1. 得到操作List类型的客户端
        ListOperations listOperations = redisTemplate.opsForList();
        //2.添加
        listOperations.leftPushAll("list","王友华","增顺","陈泳");
        //3. 获取
        System.out.println("出来的是:"+ listOperations.range("list",0,-1));

        //4. 获取大小
        System.out.println("总长度:"+listOperations.size("list"));
    }
操作集合类型数据
 /**
     * 操作set类型
     */
    @Test
    public void testSet(){
        //1. 得到操作Set类型的客户端
        SetOperations setOperations = redisTemplate.opsForSet();
        //2. 存储
        setOperations.add("set1","凤姐","如花","芙蓉姐姐","黄媚-欣望");

        //3. 获取
        Set set1 = setOperations.members("set1");
        set1.stream().forEach(s-> System.out.print(s+","));

        //4. 删除
        setOperations.remove("set1","芙蓉姐姐");

        System.out.println("删除后内容......");
        set1 = setOperations.members("set1");
        set1.stream().forEach(s-> System.out.print(s+","));

    }
操作有序集合类型数据
    /**
     * 操作set类型
     */
    @Test
    public void testSortedset(){
        //1. 得到客户端
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();

        //2. 添加
        zSetOperations.add("zset","老钟",100);
        zSetOperations.add("zset","欣望",1000);
        zSetOperations.add("zset","麟业",90);

        //3. 遍历
        Set set = zSetOperations.range("zset", 0, -1);
        for (Object key : set) {
            System.out.println(key+","+zSetOperations.score("zset",key));
        }
        //4. 修改分数
        zSetOperations.incrementScore("zset","麟业",3000);

        System.out.println("【=====修改后分数====】");
        //5. 遍历
        set = zSetOperations.range("zset", 0, -1);
        for (Object key : set) {
            System.out.println(key+","+zSetOperations.score("zset",key));
        }
    }
通用操作
 /**
     * 通用操作
     */
    @Test
    public void baseTest(){
        //1. 所有键
        Set<String> keys = redisTemplate.keys("*");
        System.out.println("=======所有键==========");
        for (String key : keys) {
            System.out.print(key+",");
        }
        System.out.println();
        //2. 判断有没有键
        Boolean flag = redisTemplate.hasKey("set");
        System.out.println("是否存在set1:"+ flag);
        //3. 类型
        System.out.println("类型:"+redisTemplate.type("set"));

        //4. 删除
        redisTemplate.delete("set");
    }

Redis序列化

序列化的使用场合:

当我们把对象存放到硬盘或者把对象通过网络传输时就需要用到序列化

序列化: 实际上就是把对象的属性以及属性值转换成一个一个的字节

需要这个类实现Seniolizable接口

反序列化
把字节恢复成对象的过程 我们称之为反序列化

redis本身是一个基于内存的key-value结构的数据库,但是它在开发的时候也支持了数据的持久化,redis中的数据要可以保存到硬盘上。

我们把key和Value要存储在redis数据库中,说白了也是将Key value存储在硬盘上,我们其实是把key对应的对象 以及value对应的对象 存储在硬盘 说白了,sname 进行序列化之后存储到硬盘,张三 进行序列化之后存储到硬盘。默认情况下 我们key和value使用的序列化方式是jdk序列化方式

posted @ 2023-07-22 15:15  YxinHaaa  阅读(7)  评论(0编辑  收藏  举报