为了实现一个类似关系数据库中的卖家信息的单表,首先我们知道单表必然可增删查改,其次为了区分先来后到又需要有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. 有关linux中出现systemctl status network.service" and "journalctl -xe" for details.

    Job for network.service failed because the control process exited with error code >**[root@mina0 ...

  2. linux 基础9-账号与身份管理

    1. linux的账号与群组 1.1 账户名称:/etc/passwd: head -n 5 /etc/password #取前5行 账号名称,对应UID 密码,早期是在这里,后来转到了/etc/sh ...

  3. 前端(HTML)+后端(Django)+数据库(MySQL):用户注册及登录演示

    1.创建一个html文件用于简单的网页注册demo <!DOCTYPE html> <html lang="en"> <head> <me ...

  4. Vs2017 NetCode EF Mysql 控制台应用

    1  运行环境   vs2017   NetCode2.0 2 NuGet  MySql.Data.EntityFrameworkCore 8.0.18   Json.Net 1.0.16 3  源代 ...

  5. 页面Header自适应屏幕

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...

  6. ubuntu---github下载太慢的解决办法

    git clone --recursive https://github.com/tensorflow/tensorflow  下载太慢了,20:05-21:17 才下载了17%,等的太急人了. ** ...

  7. Python3+Appium学习笔记08-元素定位

    appium整合了不同的自动化测试驱动程序.而新版本appium desktop 中安卓是使用UI Automator2来作为驱动程序的.以前版本是使用UI Automator1或 Selendroi ...

  8. Unknown initial character set index '255' received from server. Initial client character 解决方法

    Unknown initial character set index '255' received from server. Initial client character set can be ...

  9. C# IFormattable 接口重写

    public class Racer : IComparable<Racer>, IFormattable { public int Id { get; private set; } pu ...

  10. springAop,注解annotation + redis 实现分布式锁

    当前流行的系统,就是分布式系统.所谓分布式,我个人理解,是很多的服务分布在不同的机器上,都是相同功能模块.但是容易出现一个问题,就是并发时的问题. 我们传统的锁,只能锁住一个服务器上的方法,让其在一个 ...