0
点赞
收藏
分享

微信扫一扫

Redis项目应用场景与实例(四):集合(Set)


文章目录

  • ​​一、背景​​
  • ​​二、项目需求​​
  • ​​三、环境配置​​
  • ​​四、项目代码​​
  • ​​4.1 Redis工具类增加集合操作方法​​
  • ​​4.2 客户实体类​​
  • ​​4.3 客户信息WebApi​​
  • ​​4.4 记录并缓存客户信息实现类​​
  • ​​五、测试与验证​​
  • ​​5.1 相同信息自动去重​​
  • ​​5.2 不同集合之间的交集与差集​​
  • ​​六、源码​​

一、背景

在前三篇文章

  • ​​《Redis项目应用场景与实例(一):哈希表(Hash)》​​
  • ​​《Redis项目应用场景与实例(二):字符串(String)》​​
  • ​​《Redis项目应用场景与实例(三):队列(List)》​​ 介绍了Redis对于Hash表、字符串、队列的操作,该文将对集合(Set)的应用场景进行实际演练。

strings

hashes

lists

sets

sorted sets

封锁一个IP地址

存储用户信息

模拟队列

自动去重

以某一个条件为权重,进行排序

二、项目需求

  • 创建SpringBoot添加客户信息服务接口;
  • 通过Redis集合缓存客户信息,要求自动去重,不得重复记录。

Redis项目应用场景与实例(四):集合(Set)_redis

三、环境配置

  • 开发环境:
  • JDK 1.8
  • SpringBoot 2.2.5
  • JPA
  • Spring Security
  • Mysql 8.0
  • Redis Server 3.2.1
  • Redis Desktop Manager
  • Swagger2

– java后端项目结构

Redis项目应用场景与实例(四):集合(Set)_redis_02

四、项目代码

4.1 Redis工具类增加集合操作方法

/**
* Redis工具类
*
* @author zhuhuix
* @date 2020-06-15
* @date 2020-06-17 增加队列操作方法
* @date 2020-06-22 增加集合(set)操作方法
*/
@Component
@AllArgsConstructor
public class RedisUtils {
private RedisTemplate<Object, Object> redisTemplate;


/**
* 向集合中增加元素
*
* @param key 集合键值
* @param value 元素
* @return 添加数量
*/
public long setAdd(String key, Object value) {
return redisTemplate.opsForSet().add(key,value);
}

/**
* 向集合中批量增加元素
*
* @param key 集合键值
* @param list 元素列表
* @return 添加数量
*/
public long setAdd(String key, List<Object> list) {
return redisTemplate.opsForSet().add(key,list);
}

/**
* 集合删除指定元素
*
* @param key 集合键值
* @param value 指定元素
* @return 删除数量
*/
public long setRemove(String key, Object value) {
return redisTemplate.opsForSet().remove(key, value);
}

/**
* 集合批量删除指定元素
*
* @param key 集合键值
* @param list 指定元素列表
* @return 删除数量
*/
public long setRemove(String key, List<Object> list) {
return redisTemplate.opsForSet().remove(key, list);
}

/**
* 取出两信集合的交集
*
* @param key1 集合1键值
* @param key2 集合2键值
* @return 交集
*/
public Set<Object> setInter(String key1, String key2) {
return redisTemplate.opsForSet().intersect(key1, key2);
}

/**
* 取出多个集合的交集
*
* @param keys 键值列表
* @return 交集
*/
public Set<Object> setInte(List<Object> keys) {
return redisTemplate.opsForSet().intersect(keys);
}

/**
* 取出两个集合的差集
*
* @param key1 集合1键值
* @param key2 集合2键值
* @return 差集
*/
public Set<Object> setDifference(String key1,String key2){
return redisTemplate.opsForSet().difference(key1,key2);
}

}

4.2 客户实体类

/**
* CRM客户信息
*
* @author zhuhuix
* @date 2020-05-04
*/
@Entity
@Getter
@Setter
@Table(name = "customer")
public class Customer implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull(groups = Update.class)
private Long id;

@Column(name = "open_id")
private String openId;

/**
* 客户代码
*/
@Column(name = "customer_code")
private String customerCode;

/**
* 客户名称
*/
@Column(name = "customer_name")
private String customerName;

/**
* 首字母
*/
@Column(name = "first_letter")
private String firstLetter;

/**
* 创建时间
*/
@Column(name = "create_time")
@CreationTimestamp
private Timestamp createTime;

/**
* 更新时间
*/
@Column(name = "update_time")
@UpdateTimestamp
private Timestamp updateTime;

@Override
public String toString() {
return "Customer{" +
"customerCode='" + customerCode + '\'' +
", customerName='" + customerName + '\'' +
'}';
}
}

4.3 客户信息WebApi

@ApiOperation(value = "通过扫一扫功能上传客户信息")
@PostMapping(value = "/crmScan/{openId}")
public ResponseEntity crmScan(@RequestBody WxScanDto wxScanDto, @PathVariable String openId) {

return ResponseEntity.ok(wxMiniCrm.wxScan(wxScanDto, openId));

}

4.4 记录并缓存客户信息实现类

/**
* 微信小程序CRM实现类
*
* @author zhuhuix
* @date 2020-04-20
* @date 2020-06-17 将最新的上传信息推入Redis队列
* @date 2020-06-22 记录并将客户信息通过Redis集合缓存
*/
@Slf4j
@AllArgsConstructor
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class WxMiniCrmImpl implements WxMiniCrm {

private final UploadFileTool uploadFileTool;
private final CrmIndexRepository crmIndexRepository;
private final CustomerRepository customerRepository;
private final UserService userService;
private final RedisUtils redisUtils;

...

@Override
@Transactional(rollbackFor = Exception.class)
public Result<WxScanDto> wxScan(WxScanDto wxScanDto, String openId) {

//微信扫一扫保存客户信息
if (Constant.SAVE_CUSTOMER_INFO.equals(wxScanDto.getScanType()) && wxScanDto.getJsonObject() != null) {
try {
Customer customer = JSONObject.parseObject(wxScanDto.getJsonObject().toJSONString(), Customer.class);
Customer target = customerRepository.findByCustomerCodeAndOpenId(customer.getCustomerCode(), openId);
if (target != null) {
BeanUtils.copyProperties(customer, target, RepositoryUtil.getNullPropertyNames(customer));
} else {
target = customer;
target.setOpenId(openId);
}
wxScanDto.setReturnObject(customerRepository.save(target));
// 将用户增加的客户信息添加到redis集合中
redisUtils.setAdd(openId.concat("_customer"),customer.toString());

return new Result<WxScanDto>().ok(wxScanDto);
} catch (JSONException ex) {
throw new RuntimeException("json转换失败:" + ex.getMessage());
}

}
return new Result<WxScanDto>().error("无法处理扫一扫功能");
}


}

五、测试与验证

5.1 相同信息自动去重
  • swagger2进行接口测试
    – 多次提交相同的客户信息
  • Redis项目应用场景与实例(四):集合(Set)_应用场景_03

  • Redis Desktop Manager验证数据
    – 查看集合中的数据,实现自动去重
  • Redis项目应用场景与实例(四):集合(Set)_应用场景_04

5.2 不同集合之间的交集与差集

– 用户1通过接口添加4个客户

Redis项目应用场景与实例(四):集合(Set)_redis_05


–用户2通过接口添加3个客户

Redis项目应用场景与实例(四):集合(Set)_redis_06


– 获取用户1与用户2相同及不同的客户信息

/**
* Redis测试
*
* @author zhuhuix
* @date 2020-06-22 set测试
*/
@SpringBootTest
@Slf4j
public class TestSet {
@Test
void test() {
RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);
//获取交集:相同客户
Set<Object> setInter=redisUtils.setInter("openId1_customer","openId2_customer");
Iterator iterator = setInter.iterator();
log.info("openId1_customer与openId2_customer相同的客户为:");
while(iterator.hasNext()){
log.info(iterator.next().toString());
}
//获取差集:不同客户
Set<Object> setDiff=redisUtils.setDifference("openId1_customer","openId2_customer");
iterator = setDiff.iterator();
log.info("openId1_customer与openId2_customer不同的客户为:");
while(iterator.hasNext()){
log.warn(iterator.next().toString());
}

//获取差集:不同客户
Set<Object> setDiff1=redisUtils.setDifference("openId2_customer","openId1_customer");
iterator = setDiff1.iterator();
log.info("openId2_customer与openId1_customer不同的客户为:");
while(iterator.hasNext()){
log.warn(iterator.next().toString());
}
}
}

  • 测试结果
  • Redis项目应用场景与实例(四):集合(Set)_java_07

六、源码

​​Redis项目应用场景与实例(四)后端源码​​​​Redis项目应用场景与实例(四)前端源码​​


举报

相关推荐

0 条评论