从头开始学Redisson--------分布式集合之多值映射(MultiMap)
一、多值映射
基于Redis的Redisson的分布式RMultimap
Java对象允许Map中的一个字段值包含多个元素。什么意思呢?多值映射就是说某个多值映射(MultiMap),它的一个Key,能够存放多个值。说白了,RMutiMap<String,String>这样的泛型,实际上是的效果类似于Map<String,List<String>>。
基于列表(List)的多值映射(RListMultimap),它是在保持插入顺序的同时允许一个字段下包含重复的元素。
基于集合(Set)的多值映射(RSetMultimap),它是不允许一个字段值包含有重复的元素。
还可以为上述两种多值映射提供淘汰机制,大白话就是上面的两种多值映射能够为具体的某个元素提供过期时间。它们分别是RListMultimapCache与RSetMultimapCache。
二、使用RListMultimap缓存日志
import com.tyzhou.Constant;
import com.tyzhou.redisson.model.LogDO;
import org.redisson.api.RList;
import org.redisson.api.RListMultimap;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping(value = "redisson/map/multi")
public class MultiMapController {
private static final Logger LOGGER = LoggerFactory.getLogger(MultiMapController.class);
@Autowired
private RedissonClient redisson;
@GetMapping(value = "/add")
public void add(@RequestParam String userAccount) {
//缓存某个人的日志
RListMultimap<String, LogDO> rListMultimap =
redisson.getListMultimap(Constant.REDISSON_MAP_MULTI_LIST_LOG);
LogDO log = new LogDO(userAccount);
//存放的数据类型实际上是【String --- List<LogDO>】
rListMultimap.put(userAccount, log);
}
@GetMapping(value = "/get")
public List<LogDO> get(@RequestParam String userAccount) {
//获取某个人的日志
RListMultimap<String, LogDO> rListMultimap =
redisson.getListMultimap(Constant.REDISSON_MAP_MULTI_LIST_LOG);
RList<LogDO> logList = rListMultimap.get(userAccount);
return logList;
}
@GetMapping(value = "/clear")
public void clear(@RequestParam String userAccount) {
//清除某个人的日志
RListMultimap<String, LogDO> rListMultimap =
redisson.getListMultimap(Constant.REDISSON_MAP_MULTI_LIST_LOG);
rListMultimap.removeAll(userAccount);
}
}
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
public class LogDO {
private Integer id;
private String userAccount;
private Date operationTime;
public LogDO(String userAccount) {
this.userAccount = userAccount;
this.operationTime = new Date();
}
}
三、使用RSetMultimap缓存日志
RSetMultimap多值映射不允许一个字段值包含有重复的元素。
下面模拟为某个班级增加学生。学号不能相同,如果添加的学号相同,那么无效。
既然是RSetMultimap多值映射实现了Set接口,那么为了辨别出是同一个学生,需要重写学生对象的hashcode与equals方法。如下,如果学生对象的userAccount属性是一样的,那么认为是同一个对象。
package com.tyzhou.redisson.model;
import com.google.common.base.Objects;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentDO {
private String userAccount;
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
StudentDO studentDO = (StudentDO) o;
return Objects.equal(userAccount, studentDO.userAccount);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), userAccount);
}
}
@GetMapping(value = "/add")
public void add(@RequestParam String className,
@RequestParam String userAccount, @RequestParam String stuName) {
//添加一个学生,userAccount学号相同则认为是同一个人
RSetMultimap<String, StudentDO> setMultimap =
redisson.getSetMultimap(Constant.REDISSON_MAP_MULTI_SET_STU);
//为指定班级添加学生【同理,判断是否是同一个元素的条件是:】
setMultimap.put(className,
new StudentDO(userAccount, stuName));
}
@GetMapping(value = "/get")
public Set<StudentDO> get(@RequestParam String className) {
//获取指定班级的学生
RSetMultimap<String, StudentDO> setMultiMap =
redisson.getSetMultimap(Constant.REDISSON_MAP_MULTI_SET_STU);
return setMultiMap.get(className);
}
@GetMapping(value = "/clear")
public void clear(@RequestParam String className) {
RSetMultimap<String, StudentDO> setMultiMap =
redisson.getSetMultimap(Constant.REDISSON_MAP_MULTI_SET_STU);
setMultiMap.removeAll(className);
}