- 由于業(yè)務(wù)需求, 需要將一個集合放到redis里面, 大部分博客推薦的方法是將List整個對象做序列化。如果是這種操作的話, 其實放到redis里面的還是一整個對象,也不能享受redis提供的對集合的操作。
對redis有了解過的同學(xué)應(yīng)該,在redis里有操作list集合的命令,lpush rpush lrange...等等命令。
而spring提供的 RedisConnection 是對redis連接的封裝,也封裝了lpush等一些命令。
從而可以通過這個對象對redis操作。
直接上代碼
- 將一個list集合元素push到redis
public long setCollection(byte[] key, Collection<?> value) {
Object result = redisTemplate.execute((conn) -> {
long size = 0;
for (Object val : value) {
// 迭代list的每一個元素, push到key對應(yīng)的list
size = conn.rPush(key, SerializeUtil.serialize(val));
}
return size;
} , false);
return (long) result;
}
- 從redis獲取list集合的某一部分數(shù)據(jù)
public <T> List<T> getList(byte[] key, int page, int size) {
Object result = redisTemplate.execute((conn) -> {
// 先查詢list里面的總長度
Long len = conn.lLen(key);
// 得到偏移量
int offeset = getOffeset(page, size);
// 如果偏移量已經(jīng)大于總長度, 則直接返回null
if (offeset > len) {
return null;
}
// 得到集合里面對應(yīng)位置的數(shù)據(jù)
List<byte[]> list = conn.lRange(key, offeset, size);
List<T> listOs = Lists.newArrayList();
// 將byte數(shù)組返序列化成對象
for (byte[] bs : list) {
listOs.add((T) SerializeUtil.unserialize(bs));
}
return listOs;
} , false);
return result == null ? Lists.newArrayList() : (List<T>) result;
}
/**
* 獲取偏移量
**/
private int getOffeset(int page, int size) {
return page == 0 ? 0 : page * size;
}
- 最終, 一個基于redis list結(jié)構(gòu)的數(shù)據(jù)存儲方法就已經(jīng)完成啦~
至于存儲到redis的數(shù)據(jù)是先轉(zhuǎn)成json再getByte, 還是直接序列化成byte數(shù)組就看個人喜好了
序列化成字節(jié)效率是更高的, 但是字符串更具有可讀性
TIP: getList返回的是一個List集合, 可以根據(jù)也無需求定制自己的方法,這里只是提供一個思路
最后, 附上
SerializeUtil序列化工具類
public class SerializeUtil {
private static Logger logger = LoggerFactory.getLogger(SerializeUtil.class);
// 對象序列化成字數(shù)組
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
return baos.toByteArray();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
try {
if (oos != null) {
oos.close();
}
if (baos != null) {
baos.close();
}
} catch(Exception e) {
logger.error(e.getMessage(), e);
}
}
return null;
}
// 字節(jié)數(shù)組反序列化成對象
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try {
bais = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
try {
if (bais != null) {
bais.close();
}
if (ois != null) {
ois.close();
}
} catch(Exception e) {
logger.error(e.getMessage(), e);
}
}
return null;
}
}