Boot项目操作Redis保存用户视频浏览记录(给我弄!!!)

1.需求分析

近期项目上使用redis进行用户历史记录的定期保存,很明显是一对多的关系,看我存的redis

2.项目难点

同一短剧id只保留最新的一个集数记录,需定时刷新;数据超过7天的需定时清理。

3.方案一开发思路

果断选择list操作,发现定时无法做,又改成了zset但多数据存储又不方便,最终选择list在里面添加时间字段,循环拿出时间字段与当前时间进行比较。

方案一:

/**
 * ran
 * 用户历史记录
 */
@RestController
@RequestMapping("/tb-user-history")
public class TbUserHistoryController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * Ran
     * 方案一:利用时间过期策略删除数据
     * 保存用户记录到redis,适用于各平台数据
     */ 
    @PostMapping("/save")
    public Result saveredis(@RequestBody TbUserHistoryDTO historyDTO) throws JsonProcessingException {

        if (historyDTO.getUid() == null || historyDTO.getUid() == "") return Result.errCode_400();

//        设置统一时间格式
        String setDate = LocalDateTime.now().toString();
        historyDTO.setCreateTime(setDate);
        String uid = historyDTO.getUid();
        historyDTO.getCategoryId();//短剧id
        List<TbUserHistoryDTO> list = new ArrayList<>();
        list.add(historyDTO);

        ObjectMapper objectMapper = new ObjectMapper();

//        根据uid取出list集合,遍历list集合做判断
        List<String> redisUidList = redisTemplate.opsForList().range(uid, 0, -1);// 取出0,最后
        System.out.println("长度" + redisUidList.size());
//        遍历list集合,取出所有元素
        // 遍历列表
        ObjectMapper jsonObject = new ObjectMapper();
        if (redisUidList.size() != 0) {
            for (int i = 0; i < redisUidList.size(); i++) {
                String s = redisUidList.get(i);//两条string类型的,list数据
                JsonNode jsonNode = jsonObject.readTree(s);//转为json对象
                int shortplayId = jsonNode.get(0).get("shortplayId").asInt();//短剧id

                if (historyDTO.getShortplayId() == shortplayId) {
//                根据下标删除这条数据
                    redisTemplate.opsForList().remove(uid, i, jsonNode.toString());
//保存新数据
                    String strJson = objectMapper.writeValueAsString(list);
                    redisTemplate.opsForList().leftPush(uid, strJson);
                    return Result.ok();
                }

//             时间转为string
                String redisCreateTime = jsonNode.get(0).get("createTime").asText();
                System.out.println("redis中的时间" + redisCreateTime);
//                // 定义日期时间格式
                DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
//把redis里面的时间格式放进去,转换一下
                LocalDateTime createTime = LocalDateTime.parse(redisCreateTime, formatter);
                System.out.println("redis转换后的时间===" + createTime);
 获取当前时间
                LocalDateTime now = LocalDateTime.now();
                System.out.println("后期时间===" + now);
 计算时间差  用天数计算
                long daysBetween = ChronoUnit.DAYS.between(createTime, now);
                System.out.println("时间差" + daysBetween);
//                判断是否大于7天
                if (daysBetween > 7)
//               删除这条数据
                    redisTemplate.opsForList().remove(uid, i, jsonNode.toString());
                System.out.println("删除下标为" + i);

//如果短剧信息接口相等

            }
        }
//        list添加
        String strJson = objectMapper.writeValueAsString(list);//转成json
        redisTemplate.opsForList().leftPush(uid, strJson);//存入redis
        return Result.ok();
    }

方案二开发思路

 如果对时间过期没有强制要求可以使用裁剪list长度,保留用户最新的50条记录,因为redis每过来一条记录都是从下标0开始添加,这样50条以后的记录就会被删掉,确保冗余数据不易过大。

方案二:

 /**
     * Ran
     * 方案二
     * 保留用户前50条数据
     */
    @PostMapping("/save2")
    public Result saveredis2(@RequestBody TbUserHistoryDTO historyDTO) throws JsonProcessingException {

        if (historyDTO.getUid() == null || historyDTO.getUid() == "") return Result.errCode_400();

//        设置统一时间格式
        String uid = historyDTO.getUid();
        historyDTO.getCategoryId();//短剧id
        List<TbUserHistoryDTO> list = new ArrayList<>();
        list.add(historyDTO);

        ObjectMapper objectMapper = new ObjectMapper();

//        根据uid取出list集合,遍历list集合做判断
        List<String> redisUidList = redisTemplate.opsForList().range(uid, 0, -1);// 取出0,最后
        System.out.println("长度" + redisUidList.size());
//        遍历list集合,取出所有元素
        // 遍历列表
        ObjectMapper jsonObject = new ObjectMapper();
        if (redisUidList.size() != 0) {
            for (int i = 0; i < redisUidList.size(); i++) {
                String s = redisUidList.get(i);//两条string类型的,list数据
                JsonNode jsonNode = jsonObject.readTree(s);//转为json对象
                int shortplayId = jsonNode.get(0).get("shortplayId").asInt();//短剧id

                if (historyDTO.getShortplayId() == shortplayId) {
//                根据下标删除这条数据
                    redisTemplate.opsForList().remove(uid, i, jsonNode.toString());
//保存新数据
                    String strJson = objectMapper.writeValueAsString(list);
                    redisTemplate.opsForList().leftPush(uid, strJson);
//                截取
                    redisTemplate.opsForList().trim(uid, 0, 49);//只保留前50条数据
                    return Result.ok();
                }

            }
        }
//        list添加
        String strJson = objectMapper.writeValueAsString(list);//转成json
        redisTemplate.opsForList().leftPush(uid, strJson);//存入redis
        redisTemplate.opsForList().trim(uid, 0, 49);//只保留前50条数据
        return Result.ok();
    }

(,,´•ω•)ノ"(´っω•`。)牧码亲亲贝贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值