2023/9/24总结

Redis

Redis 是一个基于内存的键值数据库

安装

Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)_redis安装_明金同学的博客-CSDN博客

出现上面代表安装成功了

redis 一共有 16 个库

安装后 再安装图形化界面

图形界面十分方便去使用

redis数据结构介绍

redis 是 键值对的数据库  key 一般是 string 类型 但是 value 的类型 多种多样

String  类型

  • set  添加或者修改一个已经存在的String类型的键值对
  • get 获取到对应  key  的  value
  • mset  批量添加多个  String  类型的 键值对
  • mget  获取到所有  key  的 value
  • incr  让一个整型的  key  自增  1
  • incrby  让一个整型的  key  自增  并且指定 步长
  • incrbyfloat  让一个 浮点 类型 的数字自增并且指定步长
  • setnx  添加一个String 类型的 键值对  前提时 这个 key 不存在 否则不执行
  • setex  添加一个 String 类型的键值对  并且指定有效期

key 的结构  

redis 的 key 允许 有多个 单词 形成 层级结构  多个单词之间 用  :  隔开  

Hash 类型

类似于  java  中的 HashMap 结构  Hash  结构 可以将对象中的 每个  字段 独立存储  可以针对 单个字段做 CRUD

  • hset key field value 添加或者修改 hash 类型 key 的 field 的值
  • hset key field 获取一个hash类型key 的 field 的值
  • hmset 批量添加多个 hash 类型 key 的 field 的值
  • hmget 批量获取 多个 hash 类型 key 中的 所有 field 和 value
  • hgetall  获取一个hash类型的key中的所有的field 和 value
  • hkeys 获取一个hash 类型 key 中 所有的 field
  • hvals 获取一个hash 类型 的 key 中的 所有的 value
  • hincrby 让一个hash 类型 key 字段值 自增 并 指定步长
  • hsetnx 添加一个 hash 类型的 key 的 field 值 前提是这个 field 不存在 否则不执行

List  类型

redis 中 的 list 类型 与 java 中的 LinkedList 类似  可以看作 是一个 双向链表 结构 既可以支持 正向检索 也可以 支持 反向 检索

特征也与 LinkedList 类似 

  • 有序
  • 元素可以重复 
  • 插入和删除快
  • 查询速度一般
  • lpush  向 列表 左侧 插入 一个 或者 多个 元素
  • lpop 移除 并 返回 列表 左侧 第一个元素 没有则返回  nil
  • rpush  向 列表 右侧 插入 一个或者多个 元素
  • rpop 移除 并且 返回 列表 右侧 的 第一个元素
  • lrange  返回一段 下标 范围 内 的 所有 元素
  • blpop 和 brpop  与 lpop 和 rpop 类似 只不过 在 没有 元素 时 等待 指定时间 而不是直接 返回 nil

Set   类型

redis 的 set 结构 与 java 中的 HashSet 类似 可以看作 是一个 value 为 null 的 HashMap 

  • 无序
  • 元素 不可 重复
  • 查找快
  • 支持交集 并集 差集 等 功能
  • sadd 向 set 中 添加 一个多个元素
  • srem  移除 set 中的指定元素
  • scard 返回 set 中元素的个数
  • sismemery 判断 一个元素 是否存在 于 set 中
  • smemers 获取 set 中 所有 元素
  • sinter  求 集合 的 交集
  • sdiff  求 集合 的 差集
  • sunion 求 集合 的并集

SortedSet 类型

redis 中的 SortedSet 是一个可排序 的 set 集合 与 java 中的 TreeSet 有些类似  但是底层 数据结构 却 差别 很大 SortedSet 中 每一个元素 都 带有 一个 score 属性 , 可以基于 score 属性 对元素 排序 。底层 的 实现 是一个 跳表 加 hash 表

  • 可排序
  • 元素 不重复
  • 查询速度快
  • zadd  添加 一个 或 多个元素 到 sortedset 中 如果已经存在 则 更新其 score 值
  • zrem  删除 sortedset 中的一个指定元素
  • zcore  获取 sortedset 中 指定 元素 的score值
  • zrank 获取 sortedset 中的元素个数
  • zcard 获取 sortedset 中元素个数
  • zcount 统计score 值在给定范围 内 所有 元素 的个数
  • zincrby 让sortedset 的指定元素自增  步长 为指定的 increment 值
  • zrange 按照score排序后  获取指定排名 范围内的元素
  • zrangebyscore 按照 score 排序后 获取指定 score 范围内 的 元素
  • zdiff zinter zunion 求差集  交集  并集

默认排名 都是 升序 如果还想要降序 在命令的后面 添加 rev 即可

GEO 类型

BitMap  类型

HyperLog 类型

Redis 通用命令

  • keys  查看符合模板的所有key  不建议在生产环境使用
  • del  删除一个指定的key
  • exists  判断该 key 是否存在
  • expire  设置一个key的有效期  有效期到了后key会自动删除   单位是秒
  • TTL  查看一个key的剩余有效期  当TTL为 -1 时 说明该 数据 永久有效期  为 -2 时表示已经过期

Jedis 的 使用

Jedis 是 redis 在java语言上的 客户端

Java guide | Redis

使用:

新建maven项目

依赖:

<dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>4.3.1</version>
    </dependency>

测试代码:

package com.lxh;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;

public class JedisTest {
    private Jedis jedis;

    @BeforeEach
    void setUp()
    {
        //建立连接
        jedis=new Jedis("127.0.0.1",6379);
//        如果你有设置密码 就要加下面这句话 我是并没有 设置密码的
//        jedis.auth("123456");
        jedis.select(0);
    }

    @Test
    void testString ()
    {
        String result=jedis.set("name","李泽言");
        System.out.println("result ="+result);

        String name = jedis.get("name");
        System.out.println("name="+name);
    }

    @AfterEach
    void tearDown()
    {
        if (jedis!=null)
        {
            jedis.close();
        }
    }
}

Jedis 连接池

Jedis 本身 是 线程 不安全 的 ,并且 频繁 的 创建 和 销毁 会有性能损耗  因此 我们推荐大家 使用 Jedis 连接池 代替 Jedis 的 直连 方式

代码:

package com.lxh;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisClientConfig;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisConnectionFactory {

    private static JedisPool jedisPool = new JedisPool();

    static {
        JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
        //设置最大连接数
        jedisPoolConfig.setMaxTotal(8);
        //设置最大空闲数
        jedisPoolConfig.setMaxIdle(8);
        //设置最小空间数
        jedisPoolConfig.setMinIdle(0);

        jedisPool = new JedisPool(jedisPoolConfig,"127.0.0.1",6379,1000);

    }

    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

运行结果:

SpringDataRedis

SpringDataRedis 是 Spring 中数据 操作 的 模块 包含 各种 对 数据库 的 集成 其中对 Redis 的集成 模块 就叫做 SpringDataRedis 

Spring Data Redis

  •  提供了对不同 Redis 客户端的整合
  • 提供了 RedisTemplate 统一 API 来操作 Redis
  • 支持 Redis 的发布 订阅 模型
  • 支持 Redis 哨兵 和 Redis 集群
  • 支持 基于 Lettuce 的响应式编程
  • 支持 基于 JDK  JSON  字符串  Spring 对象 的数据 序列化 及 反序列化
  • 支持基于 Redis 的 JDKCollection 实现

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

SpringDataRedis 使用步骤

新建一个 基于 maven 的 spring 的项目

引入 spring-boot-starter-data-redis 依赖

<?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>3.1.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>redisData-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>redisData-demo</name>
    <description>redisData-demo</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>3.0.4</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>3.1.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.11.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.1.4</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

在 application.properties 下 写入这些

#这里是地址 localhost 对应 的 就是 127.0.0.1
spring.data.redis.host=localhost
#这里是端口号
spring.data.redis.port=6379
#如果你需要设置密码,就写这个 否则就不写
#spring.data.redis.password=12345
#当前使用的是哪一个 数据库 一共 是 下标 0 - 15
spring.data.redis.database=1
#是否使用线程池
spring.data.redis.lettuce.pool.enabled=true
#最大活动线程池个数
spring.data.redis.lettuce.pool.max-active=8
#最长等待时间 以毫秒 为单位
spring.data.redis.lettuce.pool.max-wait=2000
#这是最大 空闲 连接池 个数
spring.data.redis.lettuce.pool.max-idle=8

然后就是测试

package com.example.redisdatademo;

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 RedisDataDemoApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
    }

    @Test
    void testString()
    {
        //写入一条 String 数据
        redisTemplate.opsForValue().set("user","lizeyan");
        String user = (String) redisTemplate.opsForValue().get("user");
        System.out.println("user : "+user);
    }

}

运行 testString  能正确输出即可

SpringDataRedis  的 序列化方式

RedisTemplate 可以 接收任意 Object 作为 值 写入Redis 只不过 写入前会把Object序列化 为字节形式  默认是采用JDK序列化的 ,得到的结构就会变成 这样

缺点  可读性差,内存占用大

我们可以重写方法 来修改 存入 redis 的数据状态

package com.example.redisdatademo;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.net.UnknownHostException;

@Configuration
public class redisDataConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException
    {

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 设置key和hashKey的序列化器为String类型
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        // 设置value和hashValue的序列化器为Jackson2JsonRedisSerializer
        Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jsonRedisSerializer.setObjectMapper(objectMapper);

        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;

//
//        //创建 Template
//        RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
//        //设置连接工厂
//        redisTemplate.setConnectionFactory(redisConnectionFactory);
//        //设置序列化工具
//        GenericJackson2JsonRedisSerializer jsonRedisSerializer=new GenericJackson2JsonRedisSerializer();
//
//        //key 和 hashKey 采用 string 序列化
//        redisTemplate.setKeySerializer(RedisSerializer.string());
//        redisTemplate.setHashKeySerializer(RedisSerializer.string());
//
//        //value 和 hashValue 采用 string 序列化
//        redisTemplate.setValueSerializer(RedisSerializer.string());
//        redisTemplate.setHashValueSerializer(RedisSerializer.string());
//
//        return redisTemplate;
    }

}

要导入依赖

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

测试输出

如果按照上面这个方式 那么会需要额外的存储空间来存储 这个类的路径  为了节省 内存空间  我们并不会 使用 JSON 序列化 来处理 value 而是 使用 String 序列化 器 。要求 只能存储 String 类型的 key 和 value ,当需要 存储 java 对象 时 手动 完成对象 的序列化 和 反序列化。

Spring 默认提供了一个 StringRedisTemplate 类 它的 key 和 value 的序列化方式 默认就是String 方式 省去了 我们自定义 RedisTemplate 的过程

package com.example.redisdatademo;

import com.example.bean.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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 RedisDataDemoApplicationTests {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //JSON工具
    private static final ObjectMapper mapper=new ObjectMapper();

    @Test
    void contextLoads() {
    }

    @Test
    void testString()
    {
        //写入一条 String 数据
        redisTemplate.opsForValue().set("user","lizeyan");
        String user =(String) redisTemplate.opsForValue().get("user");
        System.out.println("user : "+user);
    }

    @Test
    void testObject()
    {
        redisTemplate.opsForValue().set("user:xm",new User("许墨",26));
        User newUser=(User) redisTemplate.opsForValue().get("user:xm");
        System.out.println(newUser);
    }

    @Test
    void testStringTemplate() throws JsonProcessingException {
        //准备对象
        User user=new User("helios",22);

        //手动序列化
        String json=mapper.writeValueAsString(user);
        //写入一条数据到 redis
        stringRedisTemplate.opsForValue().set("user:zql",json);

        //读取数据
        String val=stringRedisTemplate.opsForValue().get("user:zql");

        //反序列化
        User newUser=mapper.readValue(val,User.class);
        System.out.println("user : "+newUser);
    }

}

运行 testStringTemplate 就可以了 我们可以发现这个是没有类的路径的

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值