为了实现一个类似关系数据库中的卖家信息的单表,首先我们知道单表必然可增删查改,其次为了区分先来后到又需要有ID主键且自增长。开始考虑使用hash数据类型,因为hash是key+列1、列2...这样一来跟关系型数据库的数据模型是最像的,但满足不了第二点。所以后来考虑使用有序set,将各列作为属性封装到一个对象中,通过json序列化为String作为有序set的value。key是固定的,我们只能对有序set整体设置失效时间,无法单独针对具体元素设置失效时间。score均为自增长的序列,score是有序set之所以有序的原因。为了解决最后一个问题,自增长的主键我们另外用一个key来维护,利用redis的incr命令来实现自增长。

  上面的有序set中维护的是多个卖家的信息,而每个卖家会维护一系列订单ID列表,这样我们就能快速的根据订单ID定位到是哪个卖家了。这次没有顺序要求,当然订单是不能重复的,所以我选择无序set。废话不多说,直接看例子:

package com.crocodile.springboot.redis;

import com.crocodile.springboot.model.Merchant;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import java.io.IOException;
import java.util.*; @Component
public class JedisOperation { // redis缓存Sorted Set的key
private final static String REDIS_SORT_KEY = "merchant_sorted_set"; // json对象映射
private ObjectMapper om = new ObjectMapper(); @Autowired
private JedisPool jedisPool; // 读取applicantion中的redis相关配置项
@Bean
@ConfigurationProperties("redis")
public JedisPoolConfig jedisPoolConfig() {
return new JedisPoolConfig();
} // Jedis的实例池,从配置项的redis.host中读取redis的ip地址
@Bean(destroyMethod = "close")
public JedisPool jedisPool(@Value("${redis.host}") String host) {
return new JedisPool(jedisPoolConfig(), host);
} /**
* 加入无序set,下面已设置了无序set的失效时间,在此之后加入不影响原有失效时间
* @param key
* @param orders
*/
public void addOrdersPerHour(String key, List<Order> orders) {
try (Jedis jedis = jedisPool.getResource()) {
orders.forEach(order -> {
try {
jedis.sadd(key, order.getOrderId());
} catch (Exception e) {
}
}); }
} /**
* 遍历订单列表,放入无序set,一个月后该无序set中全部元素均失效
* @param key
* @param orders
*/
public void addOrdersPerMonth(String key, List<Order> orders) {
try (Jedis jedis = jedisPool.getResource()) {
jedis.expire(key, 60 * 60 * 24 * 30);
orders.forEach(order -> {
try {
jedis.sadd(key, order.getOrderId());
} catch (Exception e) {
}
}); }
} /**
* 获取总记录数
*
* @return
*/
public int getCounts() {
int count;
try (Jedis jedis = jedisPool.getResource()) {
count = Integer.valueOf(String.valueOf(jedis.zcard(REDIS_SORT_KEY)));
}
return count;
} /**
* 根据起始索引、结束索引查询有序set
*
* @param start
* @param end
* @return
*/
public List<Merchant> getDatas(int start, int end) { List<Merchant> merchants = new ArrayList<>();
try (Jedis jedis = jedisPool.getResource()) {
Set<String> keys = jedis.zrange(REDIS_SORT_KEY, start, end);
keys.forEach(merchantStr -> {
Merchant merchant = null;
try {
merchant = om.readValue(merchantStr, Merchant.class);
} catch (IOException e) {
}
if (merchant != null) {
merchants.add(merchant);
}
});
}
return merchants;
} /**
* 根据score(维护key为id的自增序列)添加到有序Set
*
* @param merchant
*/
public void addMerchant(Merchant merchant) {
try (Jedis jedis = jedisPool.getResource()) {
Long sequence = jedis.incr("id");
merchant.setId(sequence);
String merchantStr = om.writeValueAsString(merchant);
jedis.zadd(REDIS_SORT_KEY, sequence, merchantStr);
} catch (Exception e) {
return e.getMessage();
}
} /**
* 根据score修改有序set中的数据,先删后增
*
* @param merchant
*/
public void modifyMerchant(Merchant merchant) {
try (Jedis jedis = jedisPool.getResource()) {
String merchantStr = om.writeValueAsString(merchant);
jedis.zremrangeByScore(REDIS_SORT_KEY, merchant.getId(), merchant.getId());
jedis.zadd(REDIS_SORT_KEY, merchant.getId(), merchantStr);
} catch (Exception e) {
return e.getMessage();
}
} /**
* 根据score删除有序set中的数据
*
* @param id
* @return
*/
public void delMerchant(String id) {
try (Jedis jedis = jedisPool.getResource()) {
jedis.zremrangeByScore(REDIS_SORT_KEY, Double.valueOf(id), Double.valueOf(id));
} catch (Exception e) {
return e.getMessage();
}
}
}
public Merchant queryMerchantIdByOrderId(String orderId, List<Merchant> merchants) {
Merchant merchant = null;
try (Jedis jedis = jedisPool.getResource()) {
Iterator<Merchant> iter = merchants.iterator();
while (iter.hasNext()) {
Merchant merchantTemp = iter.next();
if (jedis.sismember(merchantTemp.getMerchantId(), orderId)) {
merchant = merchantTemp;
break;
}
}
}
return merchant;
}
 

  applicantion.properties配置文件很简单:

#Redis数据库配置
redis.host=localhost
redis.maxTotal=5
redis.maxIdle=5
redis.testOnBorrow=true

  这里没有配置端口,jedis将默认设置端口为6379。再看下redis客户端下的有序set和无序set的操作:

127.0.0.1:> incr id
(integer)
127.0.0.1:> get id
""
127.0.0.1:> zadd set_key merchantId_1
(integer)
127.0.0.1:> incr id
(integer)
127.0.0.1:> get id
""
127.0.0.1:> zadd set key merchantId_2
(error) ERR syntax error
127.0.0.1:> zadd set_key merchantId_2
(integer)
127.0.0.1:> zcard set_key
(integer)
127.0.0.1:> zrange set_key -
) "merchantId_1"
) "merchantId_2"
127.0.0.1:> zremrangebyscore set_key
(integer)
127.0.0.1:> zrange set_key -
) "merchantId_1"
127.0.0.1:> sadd merchantId_1 merchantInfo
(integer)
127.0.0.1:> expire merchantId_1
(integer)
127.0.0.1:> ttl merchantId_1
(integer)
127.0.0.1:> smembers merchantId_1
) "merchantInfo"
127.0.0.1:> sismember merchantId_1 merchantInfo
(integer)
127.0.0.1:>

  

Redis有序Set、无序Set的使用经历的更多相关文章

  1. 四:redis的sets类型 - 相关操作(有序和无序集合)

    ================四十五种(有序和无序集合):sets种类(它是一个集)=============      简介:  set它代表的集合.加入是随意添加----->无序集合    ...

  2. Redis 有序集合(sorted set),发布订阅,事务,脚本,连接,服务器(三)

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

  3. Redis 有序集合(sorted set)

    Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分数来为集合中的成员进行从小到大的排序. 有序 ...

  4. Java设置PDF有序、无序列表

    文档中的设置有序或无序列表是一种反应内容上下级关系或者内容相同属性的方式,与单纯的文字叙述相比,它能有效增强文档内容的条理性,突出重点.因此,本文将分享通过Java编程在PDF文档中设置有序或无序列表 ...

  5. redis 有序集合(zset)函数

    redis 有序集合(zset)函数 zAdd 命令/方法/函数 Adds the specified member with a given score to the sorted set stor ...

  6. Redis有序集合

    Redis有序集合类似Redis集合存储在设定值唯一性.不同的是,一个有序集合的每个成员带有分数,用于以便采取有序set命令,从最小的到最大的分数有关. Redis 有序set添加,删除和测试中的O( ...

  7. Redis 有序聚合实现排行榜功能

    排行榜功能是一个很普遍的需求.使用 Redis 中有序集合的特性来实现排行榜是又好又快的选择.Redis有序集合非常适用于有序不重复数据的存储 一般排行榜都是有实效性的,比如“用户积分榜”.如果没有实 ...

  8. redis有序集合的使用

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

  9. redis有序集合数据类型---sortedset

    一.概述 redis有序集合和集合一样,也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数. redis正式通过分数来为集合中的重圆进行从小到大的 ...

  10. 数据结构与算法简记--redis有序集合实现-跳跃表

    跳表 定义 为一个值有序的链表建立多级索引,比如每2个节点提取一个节点到上一级,我们把抽出来的那一级叫做索引或索引层.如下图所示,其中down表示down指针,指向下一级节点.以此类推,对于节点数为n ...

随机推荐

  1. fwrite、write、fread、read

    1. write和read 1.1 write: 头文件:#include<unistd.h> 原型: ssize_t write(int fd,const void*buf,size_t ...

  2. 3.Vue过滤器

    1.概念: Vue.js 允许你自定义过滤器,可被用作一些常见文本的格式化,过滤器可以用在两个地方:mustache 插值和 v-bind 表达式.过滤器应该被添加在 JavaScript 表达式的尾 ...

  3. RT-Thread--线程管理

    线程管理的功能特点 RT-Thread系统中线程是调度的最小单位: 线程分为:系统线程和用户线程,系统线程是由 RT-Thread 内核创建的线程,用户线程是由应用程序创建的线程,这两类线程都会从内核 ...

  4. idou老师教你学Istio 14:如何用K8S对Istio Service进行流量健康检查

    Istio利用k8s的探针对service进行流量健康检查,有两种探针可供选择,分别是liveness和readiness: liveness探针用来侦测什么时候需要重启容器.比如说当liveness ...

  5. 用js刷剑指offer(调整数组顺序使奇数位于偶数前面)

    题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 牛客网链接 js代码 ...

  6. ubuntu---记录. opencv3.4.7

    一.下载 https://github.com/opencv/opencv/archive/3.4.7.zip wget -c https://github.com/opencv/opencv/arc ...

  7. gorm忽略struct种的field, 不映射到表里面

    https://github.com/jinzhu/gorm/pull/1111/commits/3c01fe791514d7064791a17d8b067106866d1e2f

  8. Python中的字典分组函数(groupby,itertools)

    from operator import itemgetter # itemgetter用来去dict中的key,省去了使用lambda函数 from itertools import groupby ...

  9. 如何获得div对象的绝对坐标

    <script>             function test() {                 var $div0 = $('#0');                 va ...

  10. 06_检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不是,则提示您非管理员(使用子串对比版本)

    #!/bin/bashif [ $USER == "root" ];then #或者 if [ $UID -eq 0 ];then    yum -y install vsftpd ...