Spring整合Redis(十八)

一、Redis简介

  • Redis是一款基于键值对的NoSQL数据库,它的值支持多种数据结构:
    字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。
  • Redis将所有的数据都存放在内存中,所以它的读写性能十分惊人。
    同时,Redis还可以将内存中的数据以快照或日志的形式保存到硬盘上,以保证数据的安全性。
  • Redis典型的应用场景包括:缓存、排行榜、计数器、社交网络、消息队列等。

二、引入依赖

pom.xml

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

三、配置Redis

1.配置数据库参数

application.yml

spring:
  redis:
    database: 11 #选择数据库
    host: localhost #ip
    port: 6379  # 端口

2.编写配置类,构造RedisTemplate

将key的类型设置为String,并指定序列化的方式。

@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;
    }

}

3.示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.junit.jupiter.api.Test;

import java.util.concurrent.TimeUnit;

@SpringBootTest
public class RedisTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testStrings() {
        String redisKey = "test:count";
        // 存String
        redisTemplate.opsForValue().set(redisKey, 1);
        // 取String
        System.out.println(redisTemplate.opsForValue().get(redisKey)); // 1
        // 自增
        System.out.println(redisTemplate.opsForValue().increment(redisKey)); // 2
        // 自减
        System.out.println(redisTemplate.opsForValue().decrement(redisKey)); // 1
    }

    @Test
    public void testHashes() {
        String redisKey = "test:user";
        // 存hash
        redisTemplate.opsForHash().put(redisKey, "id", 1);
        redisTemplate.opsForHash().put(redisKey, "username", "zhangsan");
        // 取hash
        System.out.println(redisTemplate.opsForHash().get(redisKey, "id")); // 1
        System.out.println(redisTemplate.opsForHash().get(redisKey, "username")); // zhangsan
    }

    @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)); // 3
        // 获取索引处的数据
        System.out.println(redisTemplate.opsForList().index(redisKey, 0)); // 103
        // 获取范围内的数据
        System.out.println(redisTemplate.opsForList().range(redisKey, 0, 2)); // [103, 102, 101]

        // 从左边弹出数据
        System.out.println(redisTemplate.opsForList().leftPop(redisKey)); // 103
        System.out.println(redisTemplate.opsForList().leftPop(redisKey)); // 102
        System.out.println(redisTemplate.opsForList().leftPop(redisKey)); // 101
    }

    @Test
    public void testSets() {
        String redisKey = "test:teachers";
        // 将值存入集合
        redisTemplate.opsForSet().add(redisKey, "刘备", "关羽", "张飞", "赵云", "诸葛亮");

        // 值个数
        System.out.println(redisTemplate.opsForSet().size(redisKey)); // 5
        // 随机弹出一个值
        System.out.println(redisTemplate.opsForSet().pop(redisKey)); // 关羽
        // 查看值
        System.out.println(redisTemplate.opsForSet().members(redisKey)); // [刘备, 赵云, 诸葛亮, 张飞]
    }

    @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)); // 5
        // 某个值的分数
        System.out.println(redisTemplate.opsForZSet().score(redisKey, "八戒")); // 50.0
        // 某个值的排名(倒序,大到小)
        System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey, "八戒")); //4
        // 某个排名范围的数据(倒序)
        System.out.println(redisTemplate.opsForZSet().reverseRange(redisKey, 0, 2)); //[悟空, 唐僧, 沙僧]
    }

    @Test
    public void testKeys() {
        // 删除key
        redisTemplate.delete("test:user");
        System.out.println(redisTemplate.hasKey("test:user")); // false

        // 设置过期时间
        redisTemplate.expire("test:students", 10, TimeUnit.SECONDS);
    }

    // 多次访问同一个key
    @Test
    public void testBoundOperations() {
        String redisKey = "test:count";
        // 其他数据类型也有类似的绑定方法,不用每次操作都传入key
        BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);
        operations.increment();
        operations.increment();
        operations.increment();
        operations.increment();
        operations.increment();
        System.out.println(operations.get());
    }

    // 编程式事务
    @Test
    public void testTransactional() {
        // redis事务是将一批操作一块发送给服务器执行的的,
        // 所以事务内的操作不会立刻执行,因此在事务中不要查询
        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); // [1, 1, 1, [wangwu, lisi, zhangsan]]
    }

}
posted @   DaleLee  阅读(224)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示