Spring集成Redis及常见应用

本文详细介绍了如何在SpringBoot项目中引入Redis依赖,配置Redis数据库连接,创建RedisTemplate,以及使用各种Redis操作方法。还涉及了事务管理,展示了如何在代码中启用和执行事务操作。
摘要由CSDN通过智能技术生成

引入依赖

pom.xml文件导入如下依赖:

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.6.13</version>   <!--可以省略版本 由SpringBoot自动确定适配版本-->
</dependency>

配置Redis

配置Redis数据库参数

application.properties配置文件中,填写以下配置:

# RedisProperties
# 确定使用Redis的第11号数据库
spring.redis.database=11
# 配置Redis连接地址
spring.redis.host=localhost
# 配置Redis连接端口
spring.redis.port=6379
# 配置连接Redis的密码  Redis数据库无密码则不需要此配置
spring.redis.password=连接密码

配置结果如下图所示:

image

编写配置类,构造RedisTemplate

RedisConfig.class配置类如下,用于获取RedisTemplate

/**
 * @author 花木凋零成兰
 * @date 2024/3/17 14:58
 */
@Configuration
public class RedisConfig {

    /**
     * 获取访问Redis模板类
     * @param factory Redis连接工厂类 自动装配
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory); // 配置连接工厂
        // 需要配置序列化方式  将Java类型数据存到Redis数据库中
        // 设置 key 的序列化方式
        template.setKeySerializer(RedisSerializer.string());    // RedisSerializer.string()序列字符串的序列化器
        // 设置 value 的序列化方式
        template.setValueSerializer(RedisSerializer.json());    // 序列化为json
        // 设置 hash 的key的序列化方式
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置 hash 的value的序列化方式
        template.setHashValueSerializer(RedisSerializer.json());
        
        // 使配置文件中的配置生效
        template.afterPropertiesSet();
        
        return template;
    }
}

Redis操作

模板类常用方法操作如下:

操作字符串:

  • redisTemplate.opsForValue()

操作哈希:

  • redisTemplate.opsForHash()

操作列表:

  • redisTemplate.opsForList()

操作集合(无序):

  • redisTemplate.opsForSet()

操作集合(有序)

  • redisTemplate.opsForZSet()

进行测试

测试代码如下:

/**
 * @author 花木凋零成兰
 * @date 2024/3/17 15:43
 */
@SpringBootTest
@ContextConfiguration(classes = Application.class)		// 使用Application类的配置
public class RedisTest {

    @Autowired
    private RedisTemplate redisTemplate;    // 注入redisTemplate

    @Test
    public void testStrings() {
        System.out.println("测试对字符串的操作...");
        String redisKey = "test:count";
        redisTemplate.opsForValue().set(redisKey, 1);   // 存字符串数据
        System.out.println(redisTemplate.opsForValue().get(redisKey));    // 获取key对应的value

        System.out.println(redisTemplate.opsForValue().increment(redisKey));    // 自动增加key对应的value
        System.out.println(redisTemplate.opsForValue().decrement(redisKey));    // 自动减少key对应的value
    }

    @Test
    public void testHashes() {
        System.out.println("测试对哈希的操作...");
        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"));
    }

    @Test
    public void testLists() {
        System.out.println("测试对列表的操作...");
        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));
    }

    @Test
    public void testSets() {
        System.out.println("测试对(无序)集合的操作...");
        String redisKey = "test:teachers";
        // 存set数据 可一次性存多个
        redisTemplate.opsForSet().add(redisKey, "刘备", "关羽", "张飞", "赵云", "诸葛");
        // 获取set中数据个数
        System.out.println(redisTemplate.opsForSet().size(redisKey));
        // 随机弹出set中的某个数据
        System.out.println(redisTemplate.opsForSet().pop(redisKey));
        // 展示set中的数据
        System.out.println(redisTemplate.opsForSet().members(redisKey));
    }

    @Test
    public void testSortedSets() {
        System.out.println("测试对(有序)集合的操作...");
        String redisKey = "test:students";

        // 插入元素
        redisTemplate.opsForZSet().add(redisKey, "唐僧", 80);
        redisTemplate.opsForZSet().add(redisKey, "孙悟空", 90);
        redisTemplate.opsForZSet().add(redisKey, "猪八戒", 70);
        redisTemplate.opsForZSet().add(redisKey, "沙悟净", 75);
        redisTemplate.opsForZSet().add(redisKey, "白龙马", 65);

        // 统计数据个数
        System.out.println(redisTemplate.opsForZSet().size(redisKey));
        // 获取某个元素 的分数
        System.out.println(redisTemplate.opsForZSet().score(redisKey, "猪八戒"));
        // 获取某个元素 按大到小在集合的排名 的位置索引(从0开始)
        System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey, "猪八戒"));
        // 获取元素 按大到小排名的 0-2个元素
        System.out.println(redisTemplate.opsForZSet().reverseRange(redisKey, 0, 2));
    }

    @Test
    public void testKeys() {
        System.out.println("测试一些公共方法操作...");

        redisTemplate.delete("test:user");  // 删除key所对的数据
        // 判断key是否存在
        System.out.println(redisTemplate.hasKey("test:user"));
        // 设置某个key的过期时间
        redisTemplate.expire("test:students", 10, TimeUnit.SECONDS);
    }

}

测试结果如下所示:

在这里插入图片描述

优化redis多次访问同一个key

即将key绑定到一个对象上,不需要在每次对key所对应的value进行操作时,再传入key

实现代码如下:

@SpringBootTest
@ContextConfiguration(classes = Application.class)		// 使用Application类的配置
public class RedisTest {

    @Autowired
    private RedisTemplate redisTemplate;    // 注入redisTemplate

    @Test
    public void testBoundOperations() {
        System.out.println("多此访问同一个key; 将其绑定到一个对象, 即绑定对象...");
        String redisKey = "test:count";
        BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);    // 绑定key
        // 接下来对同一个key进行操作 不需要再传入key

        System.out.println(operations.get());   // 获取绑定的key 对应的值

        // 对key所对应的value进行自增 5 次
        operations.increment();
        operations.increment();
        operations.increment();
        operations.increment();
        operations.increment();

        System.out.println(operations.get());   // 获取绑定的key 对应的值
    }

}

测试结果如下:

在这里插入图片描述

Redis事务管理

redis事务机制:

启用事务后;执行某条redis命令时,不会立刻执行;而是将命令暂存到队列中,直到操作结束,提交事务时,再将队列中的所有命令发送给Redis,再执行队列中的命令.

编程式事务演示

在某个方法内的某部分代码,启用事务。

测试代码如下:

@SpringBootTest
@ContextConfiguration(classes = Application.class)		// 使用Application类的配置
public class RedisTest {
    // 编程式事务
    @Test
    public void testTransactional() {
        Object obj =  redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                // redisTemplate.execute()方法调用时;底层自动调用该execute方法
                // operations 用于执行操作命令

                String redisKey = "test:text";

                operations.multi(); // 启用事务

                // 添加数据到set
                operations.opsForSet().add(redisKey, "zhangsan", "lisi", "wangwu");

                // 因为事务还未提交 即上述添加数据命令 还未执行
                // 此时查看对应 set 集合中的数据 应该不存在上述添加数据
                System.out.println(operations.opsForSet().members(redisKey));

                return operations.exec();   // 提交事务 并结束方法调用
            }
        });
        System.out.println("obj: " + obj);    // 查看事务类型信息等
    }

}

测试结果如下:

在这里插入图片描述

即由上述测试结果,证明了,redis事务是等到操作结束后,再执行队列中的命令;且事务得到的对象结果为[操作成功次数(一次添加数据成功数据个数),操作的数据]

  • 47
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值