1. 程式人生 > 其它 >關於Redis的問題探討:為何存放集合偏向於轉String後存放而非直接存

關於Redis的問題探討:為何存放集合偏向於轉String後存放而非直接存

在檢視公司封裝的RedisService中,發現在存放集合時,集合都是先轉為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視覺化工具手動建立集合,查詢出來的結果也是如此,可以自行驗證一下。

所以這種方式獲取到的集合,將其轉換為原來物件型別比較困難,因此選擇直接將集合轉為String型別,然後取出來之後直接通過fastJson直接轉回去更加便捷。