redis系列:通过通讯录案例学习hash命令

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

前言

这一篇文章将讲述Redis中的hash类型命令,同样也是通过demo来讲述,其他部分这里就不在赘述了。

项目Github地址:https://github.com/rainbowda/learnWay/tree/master/learnRedis/case-hash

案例

demo功能是通讯录,整个demo的大致页面如下

准备工作

首先定义一个key的前缀,已经存储自增id的key

private static final String CONTACTS_KEY_PREFIX = "contacts:";
private static final String CONTACTS_ID_KEY = "contactsID";

通讯录相关的key将会以contacts:1、contacts:2、contacts:3的形式存储

redis操作对象

private RedisTemplate redisTemplate;
//string 命令操作对象
private ValueOperations valueOperations;
//hash 命令操作对象
private HashOperations hashOperatio

疑惑

如果读者和我一样是学Java的,刚听到hash时的第一反应是这个不是一个算法吗?当时我也是这样想的。那么先来看看hash在Redis中的结构,如下图(图片来源于Redis in Action)。

图片来源于Redis in Action

如果图看不懂的,我再来介绍下。其实Redis中的hash结构就和mysql中的表类似,把key当做表名,一张表中有多个列名(sub-key),每个列有自己的值(value),然后这张表只能存放一条数据。不过,这里的hash结构不会像mysql中固定好的,它可以很方便的增加删除列,例如增加sub-key3删除sub-key1.

新增

命令介绍

先来看看hash中关于新增的一些命令

命令 用例 描述
HSET HSET key field value 设置 key 指定的哈希集中指定字段的值。
HSETNX HSETNX key field value 当field不存在时,才能成功设置值
HMSET HMSET key field value [field value ...] 设置 key 指定的哈希集中指定字段的值(多个) 。

接下来看看demo中新增的功能,下图中点击+按钮,然后在弹出框中填入name和phone属性,点击提交后整个新增流程结束。

来看看后台的方法

@RequestMapping(value = "/add",method = RequestMethod.POST)
public boolean add(@RequestBody JSONObject contacts){
    //获取自增id
    Long contactsId = valueOperations.increment(CONTACTS_ID_KEY, 1);

    contacts.put("id",String.valueOf(contactsId));
    //json转map,然后存入redis
    hashOperations.putAll(CONTACTS_KEY_PREFIX+contactsId,contacts.getInnerMap());

    return true;
}
  1. 首先是获得自增id
  2. 然后将id存入到前端传过来的json对象中
  3. 调用hashOperations对象的putAll方法将对象传入到Redis中。(putAll方法其实是调用了hmset命令,源码如下)
public void putAll(K key, Map<? extends HK, ? extends HV> m) {
    if (!m.isEmpty()) {
        byte[] rawKey = this.rawKey(key);
        Map<byte[], byte[]> hashes = new LinkedHashMap(m.size());
        Iterator var5 = m.entrySet().iterator();

        while(var5.hasNext()) {
            Entry<? extends HK, ? extends HV> entry = (Entry)var5.next();
            hashes.put(this.rawHashKey(entry.getKey()), this.rawHashValue(entry.getValue()));
        }
        //调用hMSet
        this.execute((connection) -> {
            connection.hMSet(rawKey, hashes);
            return null;
        }, true);
    }
}

列表查询

命令介绍

同样先看看相关的获取值命令

命令 用例 描述
HGET HGET key field 返回 key 指定的哈希集中该字段所关联的值
HGETALL HGETALL key 返回 key 指定的哈希集中所有的字段和值。
HKEYS HKEYS key 返回 key 指定的哈希集中所有字段的名字。
HMGET HMGET key field [field ...] 返回 key 指定的哈希集中指定字段的值。
HVALS HVALS key 返回 key 指定的哈希集中所有字段的值。
HSCAN 用于迭代Hash类型中的键值对。
HGET和HGETALL命令

来看看HGET和HGETALL在redis客户端和java中是如何操作的

redis客户端执行的命令如下

hset key field1 "Hi"
hset key field1 "Hello"
hsetnx key field1 "Hello"
hsetnx key field2 " redis"
hget key field1
hgetall key

执行结果如下

下面是java代码

@Test
public void hGetAll() {
    jedis.hset("key", "field1", "Hi");
    redisTemplate.opsForHash().put("key", "field1", "Hello");

    System.out.println(jedis.hsetnx("key", "field1", "Hello"));
    System.out.println(redisTemplate.opsForHash().putIfAbsent("key", "field2", "Hello"));

    System.out.println(jedis.hget("key", "field1"));
    System.out.println(jedis.hgetAll("key"));

    //spring redisTemplate
    System.out.println(redisTemplate.opsForHash().get("key", "field1"));
    System.out.println(redisTemplate.opsForHash().entries("key"));
}
HKEYS

redis客户端执行的命令如下

hset hashKey field1 value1
hset hashKey field2 value2
hkeys hashKey

执行结果如下

下面是java代码

@Test
public void hKeys() {
    jedis.hset("hashKey", "field1", "value1");
    jedis.hset("hashKey", "field2", "value2");

    System.out.println(jedis.hkeys("hashKey"));

    //spring redisTemplate
    System.out.println(redisTemplate.opsForHash().keys("hashKey"));
    /**
     * 注:两次结果返回的顺序是不一样的,
     * 因为jedis.hkeys返回的是HashSet(内部使用HashMap)
     * redisTemplate.opsForHash().keys返回的是LinkHashSet(内部使用LinkHashMap)
     */
}
HVALS

redis客户端执行的命令如下

hmset key field1 value1 field2 value2 field3 value3
hvals key

执行结果如下

下面是java代码

@Test
public void hVals() {
    Map<String, String> map = new HashMap<>(3);
    map.put("field1", "value1");
    map.put("field2", "value2");
    map.put("field3", "value3");

    jedis.hmset("key", map);

    System.out.println(jedis.hvals("key"));

    //spring redisTemplate
    System.out.println(redisTemplate.opsForHash().values("key"));
}

查询方法代码

接着写个查询方法,将新增的内容查询出来

@RequestMapping(value = "/getList",method = RequestMethod.GET)
    public List getList(){
        List list = new ArrayList();

        //获取联系人的keys
        Set<String> keys = redisTemplate.keys(CONTACTS_KEY_PREFIX+"*");

        for (String key: keys) {
            Map entries = hashOperations.entries(key);
            list.add(entries);
        }

        return list;
    }

这个hash查询多个会不方便些,步骤如下

  1. 获取相关的key
  2. 循环查找key相关的数据
  3. 将查询出来的结果添加到list中,返回

添加属性

来看看代码

@RequestMapping(value = "/addAttr", method = RequestMethod.POST)
public boolean addAttr(@RequestBody JSONObject contacts){
    String id = contacts.getString("id");
    String fieldName = contacts.getString("fieldName");
    String fieldValue = contacts.getString("fieldValue");

    hashOperations.put(CONTACTS_KEY_PREFIX+id, fieldName, fieldValue);

    return true;
}

其实就是用hset命令进行插入

hset contacts:1 address 北京9527号

删除属性

命令介绍

命令 用例 描述
HDEL HDEL key field [field ...] 从 key 指定的哈希集中移除指定的域

redis客户端执行的命令如下

hset hDelKey filed1 filedValue1
hdel hDelKey filed1
hdel hDelKey filed1

执行结果如下

现在来看看demo中的删除属性

代码如下

@RequestMapping(value = "/delAttr", method = RequestMethod.POST)
public boolean delAttr(@RequestBody JSONObject contacts){

    String id = contacts.getString("id");
    String fieldName = contacts.getString("fieldName");
    hashOperations.delete(CONTACTS_KEY_PREFIX+id, fieldName);

    return true;
}

其他命令

命令 用例 描述
HEXISTS HEXISTS key field 返回hash里面field是否存在
HINCRBY HINCRBY key field increment 增加 key 指定的哈希集中指定字段的数值
HINCRBYFLOAT HINCRBYFLOAT key field increment 同上,加的是浮点型
HLEN HLEN key 返回 key 指定的哈希集包含的字段的数量。
HSTRLEN HSTRLEN key field 返回hash指定field的value的字符串长度

建议学习的人最好每个命令都去敲下,加深印象。下面诗句送给你们。

纸上得来终觉浅,绝知此事要躬行。————出自《冬夜读书示子聿》

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
16天前
|
NoSQL Redis 数据库
Redis的全局命令及相关误区
Redis的全局命令及相关误区
22 0
|
24天前
|
NoSQL Redis 数据库
Redis中的常用命令有哪些?
Redis常用命令包括:PING测试连接,ECHO回显,SELECT切换数据库,QUIT关闭连接;KEYS查找key,EXISTS检查存在,DEL删除key,EXPIRE设置过期时间,TTL查看剩余生存时间,TYPE检测数据类型;STRING操作如SET/GET/MSET/MGET,INCR/DECR增减计数;HASH命令如HSET/HGET/HMSET/HMGET/HGETALL管理字段;LIST操作如LPUSH/RPUSH/LPOP/RPOP/LRANGE;
10 0
|
1天前
|
存储 NoSQL 算法
Redis入门到通关之Redis数据结构-Hash篇
Redis入门到通关之Redis数据结构-Hash篇
10 1
|
1天前
|
存储 缓存 NoSQL
Redis入门到通关之Hash命令
Redis入门到通关之Hash命令
|
1天前
|
存储 缓存 NoSQL
Redis入门到通关之String命令
Redis入门到通关之String命令
|
7天前
|
存储 NoSQL Java
Redis 命令
Redis 命令
144 0
|
18天前
|
NoSQL Redis 数据库
通过migrate命令实现两个redis实例之间的数据迁移
通过migrate命令实现两个redis实例之间的数据迁移
|
存储 NoSQL Redis
Redis命令——哈希(Hash)
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。 Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
1462 0
|
存储 NoSQL Redis
redis必杀命令:哈希(Hash)
题记: Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。 Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
1018 0
|
16天前
|
NoSQL Linux Redis
06- 你们使用Redis是单点还是集群 ? 哪种集群 ?
**Redis配置:** 使用哨兵集群,结构为1主2从,加上3个哨兵节点,总计分布在3台Linux服务器上,提供高可用性。
228 0

热门文章

最新文章