当前位置: 首页 > article >正文

Redis项目中应用

1. Redis简介

Redis是一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件

官网:https://redis.io

中文网:Redis中文网

2. Redis下载与安装

2.1 Redis下载

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

  • Windows版下载地址:https://github.com/microsoftarchive/redis/releases

  • Linux版下载地址: https://download.redis.io/releases/

2.2 Redis安装

2.2.1 Windows中

Redis的Windows版属于绿色软件,直接解压即可使用,解压后目录结构如下:

2.2.2 Linux中

  1. 将Redis安装包上传到Linux

  2. 解压安装包,命令:tar -zxvf 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

安装后重点文件说明:

  • /usr/local/redis-4.0.0/src/redis-server:Redis服务启动脚本

  • /usr/local/redis-4.0.0/src/redis-cli:Redis客户端脚本

  • /usr/local/redis-4.0.0/redis.conf:Redis配置文件

3. Spring Data Redis使用

3.1 介绍

在java程序中应该如何操作Redis呢?这就需要使用Redis的Java客户端,就如同我们使用JDBC操作MySQL数据库一样。

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

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

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

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

  • ValueOperations:string数据操作

  • SetOperations:set类型数据操作

  • ZSetOperations:zset类型数据操作

  • HashOperations:hash类型的数据操作

  • ListOperations:list类型的数据操作

3.2 环境搭建

3.2.1 导入maven坐标

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

3.2.2 配置Redis数据源

在application.yml中添加:

spring:
  redis:
    host: 地址
    port: 6379
    password: 123456
    database: 8

解释说明:

database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个数据库,编号分别是从0到15。可以通过修改Redis配置文件来指定数据库的数量。

3.2.3 编写配置类,创建RedisTemplate对象

@Configuration
@Slf4j
public class RedisConfiguration {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        log.info("开始创建redis模板对象...");
        RedisTemplate redisTemplate = new RedisTemplate();
        //设置redis的连接工厂对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置redis key的序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

解释说明:

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

3.2.4 通过RedisTemplate对象操作Redis

下面测试类中进行了简单的测试:

@SpringBootTest
public class SpringDataRedisTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testRedisTemplate(){
        System.out.println(redisTemplate);
        //string数据操作
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //hash类型的数据操作
        HashOperations hashOperations = redisTemplate.opsForHash();
        //list类型的数据操作
        ListOperations listOperations = redisTemplate.opsForList();
        //set类型数据操作
        SetOperations setOperations = redisTemplate.opsForSet();
        //zset类型数据操作
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
    }
}

测试通过,说明RedisTemplate对象注入成功,并且通过该RedisTemplate对象获取操作5种数据类型相关对象。

3.3 使用示例

3.3.1 操作字符串类型数据

/**
 * 操作字符串类型的数据
 */
@Test
public void testString(){
    // 使用 redisTemplate 的 opsForValue() 操作字符串类型的数据
    
    // 1. 使用 set() 方法设置键为 "name",值为 "小明"
    redisTemplate.opsForValue().set("name", "小明");
    
    // 2. 使用 get() 方法获取键为 "name" 的值,类型为 String
    // 由于 redisTemplate 返回的值是 Object 类型,因此这里需要强制转换为 String 类型
    String city = (String) redisTemplate.opsForValue().get("name");
    
    // 3. 输出获取到的值 "name" 对应的内容,即 "小明"
    System.out.println(city);

    // 4. 使用 set() 方法设置键为 "code",值为 "1234",并且设置该键 3 分钟后过期
    // 参数说明:
    // 第一个参数是键(key),这里为 "code"
    // 第二个参数是值(value),这里为 "1234"
    // 第三个参数是过期时间,这里为 3
    // 第四个参数是时间单位,这里为分钟(TimeUnit.MINUTES)
    redisTemplate.opsForValue().set("code", "1234", 3, TimeUnit.MINUTES);

    // 5. 使用 setIfAbsent() 方法尝试设置键为 "lock" 的值为 "1",如果键不存在则设置成功
    // setIfAbsent() 方法等同于 Redis 的 SETNX(Set if Not eXists)操作
    // 如果 "lock" 不存在,设置值为 "1" 并返回 true;如果 "lock" 已经存在,返回 false
    redisTemplate.opsForValue().setIfAbsent("lock", "1");

    // 6. 再次尝试使用 setIfAbsent() 设置键为 "lock" 的值为 "2",但因为上一步已经设置了 "lock" 键的值,所以这次不会成功
    // 由于 "lock" 键已经存在,setIfAbsent() 不会修改它的值,返回 false
    redisTemplate.opsForValue().setIfAbsent("lock", "2");
}

3.3.2 操作哈希类型数据

/**
 * 操作哈希类型的数据
 */
@Test
public void testHash(){
    // 使用 redisTemplate 的 opsForHash() 来操作哈希类型数据
    HashOperations hashOperations = redisTemplate.opsForHash();

    // 1. 使用 put() 方法向哈希表 "100" 中添加键值对 "name"-"tom"
    // 这里 "100" 是哈希表的 key,"name" 是哈希表中字段的 key,"tom" 是对应的 value
    hashOperations.put("100", "name", "tom");

    // 2. 使用 put() 方法向哈希表 "100" 中添加键值对 "age"-"20"
    // "100" 是哈希表的 key,"age" 是字段的 key,"20" 是字段的值
    hashOperations.put("100", "age", "20");

    // 3. 使用 get() 方法从哈希表 "100" 中获取字段 "name" 对应的值
    // 这里获取的是哈希表 "100" 中字段 "name" 的值,返回的是 Object 类型
    String name = (String) hashOperations.get("100", "name");

    // 4. 输出获取到的字段 "name" 的值,即 "tom"
    System.out.println(name);

    // 5. 使用 keys() 方法获取哈希表 "100" 中的所有字段名称
    // 该方法返回哈希表中所有字段的 key 值,类型为 Set
    Set keys = hashOperations.keys("100");

    // 6. 输出哈希表 "100" 中的所有字段名称
    System.out.println(keys);

    // 7. 使用 values() 方法获取哈希表 "100" 中所有字段的值
    // 该方法返回哈希表中所有字段的值,类型为 List
    List values = hashOperations.values("100");

    // 8. 输出哈希表 "100" 中的所有字段值
    System.out.println(values);

    // 9. 使用 delete() 方法删除哈希表 "100" 中的字段 "age"
    // 这里 "100" 是哈希表的 key,"age" 是要删除的字段的 key
    hashOperations.delete("100", "age");
}

3.3.3 操作列表类型数据

/**
 * 操作列表类型的数据
 */
@Test
public void testList(){
    // 使用 redisTemplate 的 opsForList() 方法获取操作列表类型数据的工具
    ListOperations listOperations = redisTemplate.opsForList();

    // 1. 使用 leftPushAll() 方法,将多个元素 "a", "b", "c" 依次从左边推入列表 "mylist"
    // "mylist" 是 Redis 中的 key,元素 "a", "b", "c" 将按顺序推入列表左端
    listOperations.leftPushAll("mylist", "a", "b", "c");

    // 2. 使用 leftPush() 方法,将元素 "d" 从左边推入列表 "mylist"
    // 这个操作会使得 "d" 位于列表最左端,顺序为 ["d", "a", "b", "c"]
    listOperations.leftPush("mylist", "d");

    // 3. 使用 range() 方法获取列表 "mylist" 中指定范围的元素
    // 参数 0 表示起始索引,-1 表示结束索引(-1 代表列表的最后一个元素)
    // 该操作会返回整个列表中的所有元素
    List mylist = listOperations.range("mylist", 0, -1);

    // 4. 输出列表 "mylist" 的所有元素
    System.out.println(mylist); // 输出结果为 ["d", "a", "b", "c"]

    // 5. 使用 rightPop() 方法从右边移除列表 "mylist" 的最后一个元素
    // 此操作会移除元素 "c",使得列表变为 ["d", "a", "b"]
    listOperations.rightPop("mylist");

    // 6. 使用 size() 方法获取列表 "mylist" 的长度(元素个数)
    // 此时列表的长度应为 3,因为移除了一个元素
    Long size = listOperations.size("mylist");

    // 7. 输出列表 "mylist" 的长度
    System.out.println(size); // 输出结果为 3
}

3.3.4 操作集合类型数据

/**
 * 操作集合(Set)类型的数据
 */
@Test
public void testSet(){
    // 使用 redisTemplate 的 opsForSet() 方法获取操作集合类型数据的工具
    SetOperations setOperations = redisTemplate.opsForSet();

    // 1. 使用 add() 方法向集合 "set1" 中添加元素 "a", "b", "c", "d"
    // Redis 中的集合类型不允许重复元素,这里 "set1" 是 Redis 中的一个集合 key
    setOperations.add("set1", "a", "b", "c", "d");

    // 2. 向另一个集合 "set2" 中添加元素 "a", "b", "x", "y"
    // "set2" 是 Redis 中的另一个集合 key,元素 "a" 和 "b" 在两个集合中都有,形成交集
    setOperations.add("set2", "a", "b", "x", "y");

    // 3. 使用 members() 方法获取集合 "set1" 中的所有元素
    // 此操作返回集合中的所有成员,集合的顺序是无序的
    Set members = setOperations.members("set1");

    // 4. 输出集合 "set1" 中的所有元素
    System.out.println(members); // 可能输出为 [a, b, c, d]

    // 5. 使用 size() 方法获取集合 "set1" 的元素个数
    Long size = setOperations.size("set1");

    // 6. 输出集合 "set1" 的大小
    System.out.println(size); // 输出结果应为 4

    // 7. 使用 intersect() 方法获取集合 "set1" 和集合 "set2" 的交集
    // 交集是两个集合中共同存在的元素,此操作返回交集中的元素
    Set intersect = setOperations.intersect("set1", "set2");

    // 8. 输出两个集合的交集
    System.out.println(intersect); // 可能输出为 [a, b]

    // 9. 使用 union() 方法获取集合 "set1" 和集合 "set2" 的并集
    // 并集是两个集合中的所有元素,此操作返回并集中所有不重复的元素
    Set union = setOperations.union("set1", "set2");

    // 10. 输出两个集合的并集
    System.out.println(union); // 可能输出为 [a, b, c, d, x, y]

    // 11. 使用 remove() 方法从集合 "set1" 中移除指定的元素 "a" 和 "b"
    // 此操作会将 "a" 和 "b" 从 "set1" 中删除
    setOperations.remove("set1", "a", "b");
}

3.3.5 操作有序集合类型数据

/**
 * 操作有序集合(ZSet)类型的数据
 */
@Test
public void testZset(){
    // 使用 redisTemplate 的 opsForZSet() 方法获取操作有序集合类型数据的工具
    ZSetOperations zSetOperations = redisTemplate.opsForZSet();

    // 1. 使用 add() 方法向有序集合 "zset1" 中添加元素 "a" 并设置其分数为 10
    // Redis 中的 ZSet 是有序集合,它的每个元素都有一个分数,元素按分数从小到大排序
    zSetOperations.add("zset1", "a", 10);

    // 2. 向有序集合 "zset1" 中添加元素 "b",分数为 12
    zSetOperations.add("zset1", "b", 12);

    // 3. 向有序集合 "zset1" 中添加元素 "c",分数为 9
    zSetOperations.add("zset1", "c", 9);

    // 4. 使用 range() 方法获取有序集合 "zset1" 中所有元素
    // 参数 (0, -1) 表示获取从第 0 位到最后一位的所有元素,集合按分数从小到大排序
    Set zset1 = zSetOperations.range("zset1", 0, -1);

    // 5. 输出集合 "zset1" 中的所有元素,按分数升序排列
    System.out.println(zset1); // 可能输出为 [c, a, b],根据分数排序

    // 6. 使用 incrementScore() 方法为有序集合 "zset1" 中的元素 "c" 的分数增加 10
    // 元素 "c" 的原分数为 9,增加后变为 19
    zSetOperations.incrementScore("zset1", "c", 10);

    // 7. 使用 remove() 方法从有序集合 "zset1" 中删除指定的元素 "a" 和 "b"
    // 此操作会将元素 "a" 和 "b" 从集合中移除
    zSetOperations.remove("zset1", "a", "b");
}

3.3.6 通用命令操作

/**
 * 通用命令操作
 */
@Test
public void testCommon(){
    // 使用 redisTemplate 的 keys() 方法获取所有键(key),支持通配符 "*"
    // 例如, "*" 获取所有键,"user*" 可以获取所有以 "user" 开头的键
    Set keys = redisTemplate.keys("*");
    
    // 输出当前 Redis 数据库中所有的键
    System.out.println(keys);

    // 使用 hasKey() 方法检查 Redis 中是否存在键 "name"
    Boolean name = redisTemplate.hasKey("name");

    // 检查键 "set1" 是否存在
    Boolean set1 = redisTemplate.hasKey("set1");

    // 遍历所有获取到的键
    for (Object key : keys) {
        // 使用 type() 方法获取每个键对应的值类型,如 String、Hash、List、Set、ZSet 等
        DataType type = redisTemplate.type(key);
        
        // 输出键的类型名称
        System.out.println(type.name());
    }

    // 使用 delete() 方法删除键 "mylist" 及其对应的值
    redisTemplate.delete("mylist");
}

http://www.kler.cn/news/364673.html

相关文章:

  • 上传Gitee仓库流程图
  • Isaac Sim Docker 部署并使用过程记录
  • 模拟信号采集显示器+GPS同步信号发生器制作全过程(焊接、问题、代码、电路)
  • LeetCode_509. 斐波那契数_java
  • Golang | Leetcode Golang题解之第507题完美数
  • ANSI C、ISO C、POSIX标准、GNU的含义
  • 从 Hadoop 迁移到数据 Lakehouse 的架构师指南
  • 【日志】递归求斐波那契数列
  • 无人机之RTK定位定向技术篇
  • 自动化桌面通知:使用Plyer库实现工作提醒
  • Java根据word 模板,生成自定义内容的word 文件
  • Kmeans聚类算法简述
  • 计算机毕业设计Hadoop+Hive+Spark+Flink广告推荐系统 广告预测 广告数据分析可视化 广告爬虫 大数据毕业设计 深度学习 机器学习
  • 异地多活架构
  • 列出机器学习方向的创新点
  • Mac 安装 TIDB 并 启动集群
  • Java 如何确保 JS 不被缓存
  • mac切换java版本
  • 【OceanBase探会】云与 AI 赋能一体化数据库的创新之旅
  • 恋爱脑讲编程:Rust 的所有权概念
  • 2-132基于matlab的一种牛头刨床的运动仿真以及运动学分析
  • Vue学习笔记(三)
  • HarmonyOS第一课——HarmonyOS介绍
  • 云+AI 时代的 OceanBase
  • 雷池社区版有多个防护站点监听在同一个端口上,匹配顺序是怎么样的
  • CTFHUB技能树之XSS——过滤关键词