牛客网项目——前置技术(七):Redis

1. Redis 基本操作

在这里插入图片描述
redis官方网站:https://redis.io/
Windows资源下载地址:https://github.com/microsoftarchive/redis

  1. 安装完成配置好环境变量之后启动客户端redis-cli
    在这里插入图片描述
  2. 默认16个库,切换库select 1
    在这里插入图片描述
  3. 刷新当前库flushdb
    在这里插入图片描述

1.1 String

  1. 存入使用 set ,单词拼接使用:不使用下划线set test:count 1
    在这里插入图片描述
  2. 取使用 get,get test:count
    在这里插入图片描述
  3. 对值进行计算,加一incr test:count减一decr test:count
    在这里插入图片描述

1.2 哈希

  1. 存数据使用 hset hset test:user id 1hset test:user username zhangsan
    在这里插入图片描述
  2. 取数据使用 hget hget test:user idhget test:user username
    在这里插入图片描述

1.3 列表

  1. 在左边存数据 lpush lpush test:ids 101 102 103
    在这里插入图片描述

  2. 列表长度 llen llen test:ids
    在这里插入图片描述

  3. 从左访问具体索引值 lindex lindex test:ids 0
    在这里插入图片描述

  4. 访问某一段数据值 lrange lrange test:ids 0 2
    在这里插入图片描述

  5. 从右边弹出数据 rpop rpop test:ids
    在这里插入图片描述

1.4 集合

  1. 存入数据 sadd sadd test aaa bbb ccc ddd eee
    在这里插入图片描述

  2. 统计个数 scard scard test
    在这里插入图片描述

  3. 随机弹出数据 spop spop test
    在这里插入图片描述

  4. 显示集合中元素 smembers smembers test
    在这里插入图片描述

1.5 有序集合

  1. 存入数据 zadd zadd test1 10 aaa 20 bbb 30 ccc 40 ddd 50 eee
    在这里插入图片描述

  2. 查询个数 zcard zcard test1
    在这里插入图片描述

  3. 查询某个元素的分数 zscore zscore test1 ccc
    在这里插入图片描述

  4. 返回某个值排名 zrank zrank test1 bbb
    在这里插入图片描述

  5. 返回某个范围的数据 zrange zrange test1 0 2
    在这里插入图片描述

1.6 全局命令

  1. 查询库里一共有多少key keys *
    在这里插入图片描述

  2. 查询库里test开头的key keys test*
    在这里插入图片描述

  3. 查看某一个值的类型 type test
    在这里插入图片描述

  4. 查看某个 key 是否存在,存在返回1,不存在返回0 exists test
    在这里插入图片描述

  5. 删除某个 key,成功返回1,不成功返回0 del test
    在这里插入图片描述

  6. 设置某个 key 的过期时间(秒),成功返回1,不成功返回0 expire test 10
    在这里插入图片描述

2. Spring 整合 Redis

在这里插入图片描述

2.1 引入依赖

不用声明版本,父pom中声明了

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

如,在父pom 的 父pom 中定义了

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

2.2 配置 Redis

  1. 在 application.properties 中声明:访问哪个库,host地址,端口号
# RedisProperties
spring.redis.database=11
spring.redis.host=localhost
spring.redis.port=6379
  1. 在 config 下实现 RedisConfig 类
    1. 注入连接工厂才能访问数据库 RedisConnectionFactory factory
    2. 实例化 bean new RedisTemplate<>();
    3. 设置工厂后有访问数据库能力 template.setConnectionFactory(factory);
    4. 指定序列化方式(数据转化方式)
package com.nowcoder.community.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.RedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 设置key的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        // 设置value的序列化方式
        template.setValueSerializer(RedisSerializer.json());
        // 设置hash的key的序列化方式
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置hash的value的序列化方式
        template.setHashValueSerializer(RedisSerializer.json());

        template.afterPropertiesSet();
        return template;
    }

}

2.3 测试访问 Redis

创建测试类 RedisTests,当前 redis 11号库里啥都没有
在这里插入图片描述

注入

@Autowired
private RedisTemplate redisTemplate;

2.3.1 测试 Sting

  1. set
  2. increment
  3. decrement
  4. 控制台查看输出结果
  5. 查看 redis 11号库内容
@Test
public void testStrings() {
    String redisKey = "test:count";

    redisTemplate.opsForValue().set(redisKey, 1);

    System.out.println(redisTemplate.opsForValue().get(redisKey));
    System.out.println(redisTemplate.opsForValue().increment(redisKey));
    System.out.println(redisTemplate.opsForValue().decrement(redisKey));
}

在这里插入图片描述
在这里插入图片描述

2.3.2 测试哈希

@Test
public void testHashes() {
    String redisKey = "test:user";

    redisTemplate.opsForHash().put(redisKey, "id", 1);
    redisTemplate.opsForHash().put(redisKey, "username", "zhangsan");

    System.out.println(redisTemplate.opsForHash().get(redisKey, "id"));
    System.out.println(redisTemplate.opsForHash().get(redisKey, "username"));
}

在这里插入图片描述
在这里插入图片描述

2.3.3 测试列表

@Test
public void testLists() {
    String redisKey = "test:ids";

    redisTemplate.opsForList().leftPush(redisKey, 101);
    redisTemplate.opsForList().leftPush(redisKey, 102);
    redisTemplate.opsForList().leftPush(redisKey, 103);

    System.out.println(redisTemplate.opsForList().size(redisKey));
    System.out.println(redisTemplate.opsForList().index(redisKey, 0));
    System.out.println(redisTemplate.opsForList().range(redisKey, 0, 2));

    System.out.println(redisTemplate.opsForList().leftPop(redisKey));
    System.out.println(redisTemplate.opsForList().leftPop(redisKey));
    System.out.println(redisTemplate.opsForList().leftPop(redisKey));
}

在这里插入图片描述

2.3.4 测试集合

@Test
public void testSets() {
    String redisKey = "test:teachers";

    redisTemplate.opsForSet().add(redisKey, "刘备", "关羽", "张飞", "赵云", "诸葛亮");

    System.out.println(redisTemplate.opsForSet().size(redisKey));
    System.out.println(redisTemplate.opsForSet().pop(redisKey));
    System.out.println(redisTemplate.opsForSet().members(redisKey));
}

在这里插入图片描述

2.3.5 测试有序集合

@Test
public void testSortedSets() {
    String redisKey = "test:students";

    redisTemplate.opsForZSet().add(redisKey, "唐僧", 80);
    redisTemplate.opsForZSet().add(redisKey, "悟空", 90);
    redisTemplate.opsForZSet().add(redisKey, "八戒", 50);
    redisTemplate.opsForZSet().add(redisKey, "沙僧", 70);
    redisTemplate.opsForZSet().add(redisKey, "白龙马", 60);

    System.out.println(redisTemplate.opsForZSet().zCard(redisKey));
    System.out.println(redisTemplate.opsForZSet().score(redisKey, "八戒"));
    System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey, "八戒"));
    System.out.println(redisTemplate.opsForZSet().reverseRange(redisKey, 0, 2));
}

在这里插入图片描述

2.3.6 全局命令

@Test
public void testKeys() {
    redisTemplate.delete("test:user");

    System.out.println(redisTemplate.hasKey("test:user"));

    redisTemplate.expire("test:students", 10, TimeUnit.SECONDS);
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4 多次访问同一个 key

BoundValueOperations是访问数据类型的单词

// 多次访问同一个key
@Test
public void testBoundOperations() {
    String redisKey = "test:count";
    BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);
    operations.increment();
    operations.increment();
    operations.increment();
    operations.increment();
    operations.increment();
    System.out.println(operations.get());
}

2.5 编程式事务

事务内命令不会立即执行,提交后统一执行
使用编程式事务进行管理,声明式事务用的少

  1. 调用 redisTemplate ,方法内部做匿名实现
  2. SessionCallback() 里方法execute重写,内部实现事务逻辑
  3. 启用事务 operations.multi();
  4. 提交事务 operations.exec();
// 编程式事务
@Test
public void testTransactional() {
    Object obj = redisTemplate.execute(new SessionCallback() {
        @Override
        public Object execute(RedisOperations operations) throws DataAccessException {
            String redisKey = "test:tx";

            operations.multi();

            operations.opsForSet().add(redisKey, "zhangsan");
            operations.opsForSet().add(redisKey, "lisi");
            operations.opsForSet().add(redisKey, "wangwu");

            System.out.println(operations.opsForSet().members(redisKey));

            return operations.exec();
        }
    });
    System.out.println(obj);
}

在这里插入图片描述

3. 高级数据类型

在这里插入图片描述

3.1 HyperLogLog

3.1.1 统计20万个重复数据的独立总数

// 统计20万个重复数据的独立总数.
@Test
public void testHyperLogLog() {
    String redisKey = "test:hll:01";

    for (int i = 1; i <= 100000; i++) {
        redisTemplate.opsForHyperLogLog().add(redisKey, i);
    }

    for (int i = 1; i <= 100000; i++) {
        int r = (int) (Math.random() * 100000 + 1);
        redisTemplate.opsForHyperLogLog().add(redisKey, r);
    }

    long size = redisTemplate.opsForHyperLogLog().size(redisKey);
    System.out.println(size);
}

在这里插入图片描述

3.1.2 将3组数据合并, 再统计合并后的重复数据的独立总数

@Test
public void testHyperLogLogUnion() {
    String redisKey2 = "test:hll:02";
    for (int i = 1; i <= 10000; i++) {
        redisTemplate.opsForHyperLogLog().add(redisKey2, i);
    }

    String redisKey3 = "test:hll:03";
    for (int i = 5001; i <= 15000; i++) {
        redisTemplate.opsForHyperLogLog().add(redisKey3, i);
    }

    String redisKey4 = "test:hll:04";
    for (int i = 10001; i <= 20000; i++) {
        redisTemplate.opsForHyperLogLog().add(redisKey4, i);
    }

    String unionKey = "test:hll:union";
    redisTemplate.opsForHyperLogLog().union(unionKey, redisKey2, redisKey3, redisKey4);

    long size = redisTemplate.opsForHyperLogLog().size(unionKey);
    System.out.println(size);
}

在这里插入图片描述

3.2 bitmap

3.2.1 统计一组数据的布尔值

@Test
public void testBitMap() {
    String redisKey = "test:bm:01";

    // 记录
    redisTemplate.opsForValue().setBit(redisKey, 1, true);
    redisTemplate.opsForValue().setBit(redisKey, 4, true);
    redisTemplate.opsForValue().setBit(redisKey, 7, true);

    // 查询
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 0));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 1));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 2));

    // 统计
    Object obj = redisTemplate.execute(new RedisCallback() {
        @Override
        public Object doInRedis(RedisConnection connection) throws DataAccessException {
            return connection.bitCount(redisKey.getBytes());
        }
    });

    System.out.println(obj);
}

在这里插入图片描述

3.2.2 统计3组数据的布尔值, 并对这3组数据做OR运算

// 统计3组数据的布尔值, 并对这3组数据做OR运算.
@Test
public void testBitMapOperation() {
    String redisKey2 = "test:bm:02";
    redisTemplate.opsForValue().setBit(redisKey2, 0, true);
    redisTemplate.opsForValue().setBit(redisKey2, 1, true);
    redisTemplate.opsForValue().setBit(redisKey2, 2, true);

    String redisKey3 = "test:bm:03";
    redisTemplate.opsForValue().setBit(redisKey3, 2, true);
    redisTemplate.opsForValue().setBit(redisKey3, 3, true);
    redisTemplate.opsForValue().setBit(redisKey3, 4, true);

    String redisKey4 = "test:bm:04";
    redisTemplate.opsForValue().setBit(redisKey4, 4, true);
    redisTemplate.opsForValue().setBit(redisKey4, 5, true);
    redisTemplate.opsForValue().setBit(redisKey4, 6, true);

    String redisKey = "test:bm:or";
    Object obj = redisTemplate.execute(new RedisCallback() {
        @Override
        public Object doInRedis(RedisConnection connection) throws DataAccessException {
            connection.bitOp(RedisStringCommands.BitOperation.OR,
                    redisKey.getBytes(), redisKey2.getBytes(), redisKey3.getBytes(), redisKey4.getBytes());
            return connection.bitCount(redisKey.getBytes());
        }
    });

    System.out.println(obj);

    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 0));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 1));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 2));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 3));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 4));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 5));
    System.out.println(redisTemplate.opsForValue().getBit(redisKey, 6));
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平什么阿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值