使用RedisTemplate实现根据用户喜好推荐电影类型

前言

RedisTemplat提供了对redis的各种操作

具体实现细节

1、创建一个Maven项目,在pom.xml中添加RedisTemplat的依赖

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

2、在application.properties中配置redis连接

#redis连接
spring.redis.database=1 #具体操作哪个数据库
spring.redis.host=127.0.0.1
spring.redis.port=6379

3、实现方式(controller)这里直接使用controller层来实现业务层,不在写接口层和业务层。

   //注入RedisTemplate 
   @Autowired
   private RedisTemplate redisTemplate;

     /**
     * 用户刚进入的时候
     * 判断redis里面是否存在用户喜爱列表,如果没有
     * 则添加喜爱列表
     * 有
     * 则不添加服务列表
     * 不管是刚添加的还是以前就存在的
     * 都可以查出用户喜爱前三的电影类型(用户第一次进来喜好刚创建都为0,系统默认排序查询)
     */
    @RequestMapping("express")
    @ResponseBody
    public String express(String phone){
        Boolean servers = redisTemplate.hasKey(phone);
        //判断redis里面是否存在用户喜爱的电影类型列表
        if(servers == false){
            //没有,添加数据到redis
            redisTemplate.boundZSetOps(phone).add("搞笑",0);
            redisTemplate.boundZSetOps(phone).add("综艺",0);
            redisTemplate.boundZSetOps(phone).add("恐怖",0);
            redisTemplate.boundZSetOps(phone).add("歌舞",0);
            redisTemplate.boundZSetOps(phone).add("历史",0);
            redisTemplate.boundZSetOps(phone).add("古装",0);
            redisTemplate.boundZSetOps(phone).add("科幻",0);
            redisTemplate.boundZSetOps(phone).add("仙侠",0);
        }
        //获取用户点击率前三的电影类型,只显示电影类型
        Set<String> server = redisTemplate.boundZSetOps(phone).reverseRange(0,2);
        //显示电影类型和点击率(次数)
        Set<String> score = redisTemplate.boundZSetOps(phone).reverseRangeWithScores(0,2);
        //转换格式
        String scores = JsonUtil.obj2String(score);
        String result = JsonUtil.obj2String(server);
        return result;
    }

4、JsonUtil转换格式工具

package com.yy.util;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
public class JsonUtil {

    private static ObjectMapper objectMapper = new ObjectMapper();

    //对象转字符串
    public static <T> String obj2String(T obj) {
        if (obj == null) {
            return null;
        }
        try {
            return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //字符串转对象
    public static <T> T string2Obj(String str, Class<T> clazz) {
        if (str == null || str.isEmpty() || clazz == null) {
            return null;
        }
        try {
            return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

5、使用接口测试工具进行测试
在这里插入图片描述
6、看一下redis里面的数据
在这里插入图片描述
7、查询爱好的完成了,下面开始获取用户浏览的次数

    /**
     *记录用户点击意图的次数
     *每查看一次电影的类型
     *电影的对应类型的浏览量就会加1
     * @param phone
     * @param serverType
     */
    @RequestMapping("serverList")
    @ResponseBody
    public void serverList(String phone,String serverType){
        switch (serverType){
            case "搞笑":
                redisTemplate.boundZSetOps(phone).incrementScore("搞笑",1);
                break;
            case "综艺":
                redisTemplate.boundZSetOps(phone).incrementScore("综艺",1);
                break;
            case "恐怖":
                redisTemplate.boundZSetOps(phone).incrementScore("恐怖",1);
                break;
            case "歌舞":
                redisTemplate.boundZSetOps(phone).incrementScore("歌舞",1);
                break;
            case "历史":
                redisTemplate.boundZSetOps(phone).incrementScore("历史",1);
                break;
            case "古装":
                redisTemplate.boundZSetOps(phone).incrementScore("古装",1);
                break;
            case "科幻":
                redisTemplate.boundZSetOps(phone).incrementScore("科幻",1);
                break;
            case "仙侠":
                redisTemplate.boundZSetOps(phone).incrementScore("仙侠",1);
                break;
        }
    }

8、用接口测试工具测试
在这里插入图片描述
9、然后返回第一个查询用户喜好电影类型的接口
在这里插入图片描述
10、再看一下redis数据库里面的值
在这里插入图片描述
到此结束!!!

<think>嗯,用户想了解如何通过RedisTemplate实现Redis的数据持久化。首先,我需要回忆一下Redis的持久化机制。Redis主要有两种持久化方式:RDB和AOF,还有混合持久化。RDB是生成快照,AOF记录每个写操作。混合持久化结合两者,重启时用RDB和AOF来恢复数据。 接下来,用户提到使用RedisTemplate,所以需要结合Spring Boot的配置。记得在Spring Boot中,通常通过配置文件application.yml来设置Redis的连接信息,比如host、port、password,还有持久化相关的配置,比如aof-use-rdb-preamble是否开启混合持久化。不过,RedisTemplate本身是客户端工具,持久化配置主要在Redis服务器端设置,但客户端需要正确配置连接池等参数以确保数据正确写入。 然后,用户需要具体的配置示例。我应该先展示pom依赖,引入spring-boot-starter-data-redis。然后是application.yml中的配置,包括Redis服务器地址、连接池参数,可能还要设置lettuce.pool相关参数。此外,如果需要启用AOF,应该在Redis服务器的配置文件redis.conf中设置appendonly yes,但用户可能想知道如何在Spring Boot中关联这些配置。需要说明的是,应用层的配置主要是连接服务器,而持久化策略需要在Redis服务端配置。 接下来是RedisTemplate使用。需要配置RedisTemplate的序列化方式,默认的JDK序列化可读性差,通常建议使用StringRedisSerializer,或者JSON序列化器。添加一个配置类,比如RedisCacheConfig,通过@Bean定义RedisTemplate,并设置key和value的序列化方式。 然后,使用Spring Cache集成Redis,通过注解如@Cacheable、@CachePut、@CacheEvict来管理缓存。这部分虽然属于缓存管理,但也和持久化有关,因为数据写入Redis后,持久化策略会影响数据的恢复。需要给出一个示例,比如UserService中使用这些注解,并展示测试类。 用户可能还会关心数据一致性问题,比如缓存雪崩、穿透、击穿,以及如何保持Redis和MySQL的数据一致性。但问题主要是持久化,所以需要集中在配置和持久化方法上。不过,引用中提到的混合持久化(Redis 4.0+)可以在重启时更快恢复数据,这点需要提到,并说明在配置文件中如何启用。 需要确保回答中提到的配置步骤正确,比如在application.yml中设置正确的属性,配置类的编写,以及代码示例的正确性。同时,引用相关的参考文献,比如引用[2]和[4]关于持久化方式及混合持久化的内容,以及引用[3]中提到的HyperLogLog,但可能不相关,所以主要引用[2]和[4]。 最后,生成相关问题,比如如何选择RDB和AOF,如何保证数据一致性,Redis持久化的问题及解决方案等。这样用户如果有进一步的问题,可以继续参考。</think>### 通过 RedisTemplate 实现 Redis 数据持久化的方法及配置示例 #### 1. Redis 持久化机制概述 Redis 数据持久化主要通过以下两种方式实现: - **RDB (快照持久化)**:定期生成数据快照(默认文件 `dump.rdb`),适合大规模数据恢复,但可能丢失最后一次快照后的数据[^2][^4]。 - **AOF (追加文件持久化)**:记录每个写操作命令,重启时重放命令恢复数据,数据完整性更高,但文件体积较大。 - **混合持久化(Redis 4.0+)**:结合 RDB 和 AOF,重启时先加载 RDB 快照,再重放增量 AOF 日志,平衡速度与安全性。 #### 2. Spring Boot 中配置 RedisTemplate ##### 2.1 添加依赖与基础配置 **pom.xml 依赖**: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` **application.yml 配置**: ```yaml spring: redis: host: localhost port: 6379 password: 123456 database: 0 lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0 # 若需启用 AOF,需在 Redis 服务端配置 appendonly yes ``` ##### 2.2 配置 RedisTemplate 序列化 添加配置类 `RedisCacheConfig.java`,定义序列化方式: ```java @Configuration public class RedisCacheConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); // Key 使用字符串序列化 template.setKeySerializer(new StringRedisSerializer()); // Value 使用 JSON 序列化 template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } } ``` #### 3. 使用 RedisTemplate 操作数据 通过注入 `RedisTemplate` 实现数据读写: ```java @Autowired private RedisTemplate<String, Object> redisTemplate; public void saveData(String key, Object value) { redisTemplate.opsForValue().set(key, value); } public Object getData(String key) { return redisTemplate.opsForValue().get(key); } ``` #### 4. 结合 Spring Cache 实现缓存持久化 使用注解管理缓存生命周期,数据操作会自动同步到 Redis: ```java @Service public class UserServiceImpl implements UserService { @Cacheable(value = "user", key = "#id") // 优先从缓存读取 public User getUserById(Long id) { return userRepository.findById(id); } @CachePut(value = "user", key = "#user.id") // 更新缓存 public User updateUser(User user) { return userRepository.save(user); } @CacheEvict(value = "user", key = "#id") // 删除缓存 public void deleteUser(Long id) { userRepository.deleteById(id); } } ``` #### 5. Redis 服务端持久化配置 在 Redis 配置文件 `redis.conf` 中启用混合持久化: ```conf appendonly yes # 启用 AOF aof-use-rdb-preamble yes # 启用混合持久化 ``` --- ### 关键注意事项 1. **持久化策略选择**: - 高数据安全性:优先使用 AOF 或混合持久化[^2]。 - 高性能恢复:选择 RDB。 2. **数据一致性**: - 通过 `@CacheEvict` 和事务机制保证缓存与数据库的一致性。 3. **性能优化**: - 调整 AOF 重写频率(`auto-aof-rewrite-percentage`)和 RDB 快照间隔(`save` 配置)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值