- 由于业务需求, 需要将一个集合放到redis里面, 大部分博客推荐的方法是将List整个对象做序列化。如果是这种操作的话, 其实放到redis里面的还是一整个对象,也不能享受redis提供的对集合的操作。
对redis有了解过的同学应该,在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对应的list
size = conn.rPush(key, SerializeUtil.serialize(val));
}
return size;
} , false);
return (long) result;
}
- 从redis获取list集合的某一部分数据
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);
// 如果偏移量已经大于总长度, 则直接返回null
if (offeset > len) {
return null;
}
// 得到集合里面对应位置的数据
List<byte[]> list = conn.lRange(key, offeset, size);
List<T> listOs = Lists.newArrayList();
// 将byte数组返序列化成对象
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结构的数据存储方法就已经完成啦~
至于存储到redis的数据是先转成json再getByte, 还是直接序列化成byte数组就看个人喜好了
序列化成字节效率是更高的, 但是字符串更具有可读性
TIP: getList返回的是一个List集合, 可以根据也无需求定制自己的方法,这里只是提供一个思路
最后, 附上
SerializeUtil
序列化工具类
public class SerializeUtil {
private static Logger logger = LoggerFactory.getLogger(SerializeUtil.class);
// 对象序列化成字数组
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;
}
// 字节数组反序列化成对象
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;
}
}