关于Redis的问题探讨(一):为何存放集合偏向于转String后存放而非直接存

在查看公司封装的RedisService中,发现在存放集合时,集合都是先通过fastJson转为String,再进行存放,而非直接存放对象本身。

对此产生疑问,因为转String存放后再取出,又要转一次才可以恢复集合,而就算使用fastJson也会消耗性能,那为何要这么做呢? 所以现在就直接上手一下,找出原因。

IRedisService

import java.util.Collection;
import java.util.List;
​
public interface IRedisService {
​
    List lRange(final String key, long start, long end);
​
    Long rightPushAll(final String key, Collection value);
​
}

RedisServiceImpl

import com.zyuan.boot.redis.IRedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
​
import java.util.Collection;
import java.util.List;
​
@Service
public class RedisServiceImpl implements IRedisService {
​
    private static final Logger log = LoggerFactory.getLogger(RedisServiceImpl.class);
​
    @Autowired
    private RedisTemplate redisTemplate;
​
    @Override
    public List lRange(String key, long start, long end) {
        List result = null;
        try {
            result = redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            log.error("redis range失败:" + e.getMessage());
        }
        return result;
    }
​
    @Override
    public Long rightPushAll(String key, Collection value) {
        Long result = null;
        try {
            result = redisTemplate.opsForList().rightPushAll(key, value);
        } catch (Exception e) {
            log.error("redis push all失败:" + e.getMessage());
        }
        return result;
    }
​
}

ThisIsDTO:用于存入Redis中

@Data
public class ThisIsDTO implements Serializable {
​
    private String name;
​
    private Integer age;
​
    private Long time;
​
    private Long iiid;
​
}

测试类

import com.zyuan.boot.redis.dto.ThisIsDTO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
​
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
​
@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisServiceTest {
​
    @Autowired
    private IRedisService redisService;
​
    @Test
    public void testRightPushAll() {
        String key = "right_push_all_01";
        List<ThisIsDTO> addDTOList = getAddDTOList();
        Long result = redisService.rightPushAll(key, addDTOList);
        System.out.println(result);
    }
​
    private List<ThisIsDTO> getAddDTOList() {
        List<ThisIsDTO> addDTOList = new ArrayList<>();
        for (int i = 4; i <= 7; i++) {
            ThisIsDTO dto = new ThisIsDTO();
            String name = "name" + i + i;
            Integer age = i*30;
            Long time = i*20L;
            dto.setName(name);
            dto.setAge(age);
            dto.setTime(time);
            addDTOList.add(dto);
        }
        return addDTOList;
    }
​
}

执行testRightPushAll,通过Redis可视化工具查看是否添加成功:

先通过对象的方式来存储查出的数据

    @Test
    public void testLRange() {
        String key = "right_push_all_01";
        List<ThisIsDTO> dtoList = redisService.lRange(key, 0, -1);
        System.out.println(dtoList.toString());
        for (ThisIsDTO thisIsDTO : dtoList) {
            String name = thisIsDTO.getName();
        }
    }

在for处打个断点,debug运行

数据确实查询成功

但是继续运行,发现报错了

看报错信息,LinkedHashMap不能转换为ThisIsDTO类型,

所以,获取到的集合,其实是 List<LinkedHashMap<String, Object>>,

通过LinkedHashMap来存放数据:

@Test
    public void testLRange() {
        String key = "right_push_all_01";
        List<LinkedHashMap<String, Object>> linkedHashMapList = redisService.lRange(key, 0, -1);
        for (LinkedHashMap<String, Object> linkedHashMap : linkedHashMapList) {
            for (String concurrentKey : linkedHashMap.keySet()) {
                Object value = linkedHashMap.get(concurrentKey);
                System.out.println(concurrentKey + "--->" + value);
            }
            System.out.println("=============");
        }
    }

再次运行,查看控制台打印信息:

东西都正常查出来了。

同样的,通过Redis可视化工具手动创建集合,查询出来的结果也是如此,可以自行验证一下。

所以这种方式获取到的集合,将其转换为原来对象类型比较困难,因此使用fastJson将集合转为String类型,然后取出来之后直接通过fastJson直接转回去更加便捷。

posted @ 2022-05-10 17:06  LonZyuan  阅读(453)  评论(0编辑  收藏  举报