redis系列:通过通讯录案例学习hash命令
前言
这一篇文章将讲述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中的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;
}
首先是获得自增id
然后将id存入到前端传过来的json对象中
调用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查询多个会不方便些,步骤如下
- 获取相关的key
- 循环查找key相关的数据
- 将查询出来的结果添加到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系列:通过通讯录案例学习hash命令的更多相关文章
- redis系列:通过文章点赞排名案例学习sortedset命令
前言 这一篇文章将讲述Redis中的sortedset类型命令,同样也是通过demo来讲述,其他部分这里就不在赘述了. 项目Github地址:https://github.com/rainbowda/ ...
- redis系列:通过共同好友案例学习set命令
前言 这一篇文章将讲述Redis中的set类型命令,同样也是通过demo来讲述,其他部分这里就不在赘述了. 项目Github地址:https://github.com/rainbowda/learnW ...
- redis系列:通过队列案例学习list命令
前言 这一篇文章将讲述Redis中的list类型命令,同样也是通过demo来讲述,其他部分这里就不在赘述了. 项目Github地址:https://github.com/rainbowda/learn ...
- redis系列:通过日志案例学习string命令
前言 该文章将通过一个小demo将讲述Redis中的string类型命令.demo将以springboot为后台框架快速开发,iview前端框架进行简单的页面设计,为了方便就不使用DB存储数据了,直接 ...
- Python操作redis系列以 哈希(Hash)命令详解(四)
# -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host=") 1. Hset 命令用于 ...
- Redis系列(二):Redis的数据类型及命令操作
原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...
- Redis系列(二):Redis的5种数据结构及其常用命令
上一篇博客,我们讲解了什么是Redis以及在Windows和Linux环境下安装Redis的方法, 没看过的同学可以点击以下链接查看: Redis系列(一):Redis简介及环境安装. 本篇博客我们来 ...
- Redis系列之-—Redis-cli命令总结【转】
Redis-cli命令最新总结 参考资料: http://redisdoc.com/ 或者 http://doc.redisfans.com http://redis.io/commands 一. 进 ...
- Redis系列-存储hash主要操作命令
Redis系列-存储篇hash主要操作函数小结 hash是一些列key value(field value)的映射表.常常用其存储一些对象实例.相对于把一个对象的各个字段存储为string,存储为ha ...
随机推荐
- EntityFramework 学习 一 创建实体数据模型 Create Entity Data Model
1.用vs2012创建控制台程序 2.设置项目的.net 版本 3.创建Ado.net实体数据模型 3.打开实体数据模型向导Entity Framework有四种模型选择 来自数据库的EF设计器(Da ...
- javascript作用域与闭包
Javasript作用域概要 在javascript中,作用域是执行代码的上下文,作用域有三种类型: 1) 全局作用域 2) 局部作用域(函数作用域) 3) eval作用域 var foo = ...
- MySQL中处理Null时要注意两大陷阱
MySQL数据库是一个基于结构化数据的开源数据库.SQL语句是MySQL数据库中核心语言.不过在MySQL数据库中执行SQL语句,需要小心两个陷阱. 陷阱一:空值不一定为空 空值是一个比较特殊的字段. ...
- NET 平台下的WebService 简单使用
一句话理解:提供可供外部访问的方法,实现跨平台访问 注意: 在客户端是添加“服务引用”,而不是引用 当服务端更新了服务之后,在客户端,一定也要“更新服务” 当要执行异常调用时,要在前台.aspx的头部 ...
- Linux-Rsync命令参数详解
在对rsync服务器配置结束以后,下一步就需要在客户端发出rsync命令来实现将服务器端的文件备份到客户端来.rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进 ...
- cocos2d-x 中 xml 文件读取
实现类 CXmlParse 啥也不说了 直接上硬货 believe yourself 一看就明白 CXmlParse.h #ifndef __C_XML_PARSE__ #define __C ...
- 微信非全屏播放设置(仅Iphone)
由于微信X5内核强制视频全屏,用X5自带内核播放,一般内嵌视频打开播放就会被全屏. ihpone里面可以通过设置 x-webkit-airplay="true" webkit-pl ...
- Linux Shell 判断块设备节点是否存在
/************************************************************************* * Linux Shell 判断块设备节点是否存在 ...
- Oracle 12c 多租户配置和修改 CDB 和 PDB 参数
1. 配置CDB 实例参数,影响CDB与所有 PDB为CDB配置例程参数相对于对于非CDB的数据库是变化不太.ALTER SYSTEM命令用于设置初始化参数,与使用ALTER DATABASE命令修改 ...
- 洛谷 P4546 & bzoj 5020 在美妙的数学王国中畅游 —— LCT+泰勒展开
题目:https://www.luogu.org/problemnew/show/P4546 先写了个55分的部分分,直接用LCT维护即可,在洛谷上拿了60分: 注意各处 pushup,而且 spla ...