前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >redis系列:通过通讯录案例学习hash命令

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

作者头像
云枭
发布2019-03-01 10:22:29
6690
发布2019-03-01 10:22:29
举报
文章被收录于专栏:fixzdfixzd

前言

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

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

案例

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

准备工作

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

代码语言:javascript
复制
private static final String CONTACTS_KEY_PREFIX = "contacts:";
private static final String CONTACTS_ID_KEY = "contactsID";

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

redis操作对象

代码语言:javascript
复制
private RedisTemplate redisTemplate;
//string 命令操作对象
private ValueOperations valueOperations;
//hash 命令操作对象
private HashOperations hashOperatio

疑惑

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

图片来源于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属性,点击提交后整个新增流程结束。

来看看后台的方法

代码语言:javascript
复制
@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命令,源码如下)
代码语言:javascript
复制
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客户端执行的命令如下

代码语言:javascript
复制
hset key field1 "Hi"
hset key field1 "Hello"
hsetnx key field1 "Hello"
hsetnx key field2 " redis"
hget key field1
hgetall key

执行结果如下

下面是java代码

代码语言:javascript
复制
@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客户端执行的命令如下

代码语言:javascript
复制
hset hashKey field1 value1
hset hashKey field2 value2
hkeys hashKey

执行结果如下

下面是java代码

代码语言:javascript
复制
@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客户端执行的命令如下

代码语言:javascript
复制
hmset key field1 value1 field2 value2 field3 value3
hvals key

执行结果如下

下面是java代码

代码语言:javascript
复制
@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"));
}
查询方法代码

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

代码语言:javascript
复制
@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中,返回

添加属性

来看看代码

代码语言:javascript
复制
@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命令进行插入

代码语言:javascript
复制
hset contacts:1 address 北京9527号

删除属性

命令介绍

命令

用例

描述

HDEL

HDEL key field [field ...]

从 key 指定的哈希集中移除指定的域

redis客户端执行的命令如下

代码语言:javascript
复制
hset hDelKey filed1 filedValue1
hdel hDelKey filed1
hdel hDelKey filed1

执行结果如下

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

代码如下

代码语言:javascript
复制
@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的字符串长度

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 案例
  • 准备工作
  • 疑惑
  • 新增
    • 命令介绍
    • 列表查询
      • 命令介绍
        • HGET和HGETALL命令
        • HKEYS
        • HVALS
      • 查询方法代码
      • 添加属性
      • 删除属性
        • 命令介绍
        • 其他命令
        相关产品与服务
        云数据库 Redis
        腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档