目录
[lpush lrange rpush](#lpush lrange rpush)
[rpush llen](#rpush llen)
[rpop lpop blpop](#rpop lpop blpop)
[hset hget hmget](#hset hget hmget)
[hkeys hvals hexists](#hkeys hvals hexists)
前言:
在上一篇文章我们介绍了string的基本使用,并且发现几乎唯一的难点就是使用迭代器方面,并且我们从上篇的迭代器简单引出了五种迭代器,分别是输入迭代器,输出迭代器,前向迭代器,双向迭代器,随机迭代器,那么这几种迭代器是我们在C++学习的时候没有具体学习的,当然,在这里我们也是简单了解了一下。
在本文,我们就通过Redis的客户端的方式使用一下list和hash对应的API。
废话不多说,直接进入主题。
list
Redis中list,也成为列表,涉及到的API有:lpush rpush lrange lpop rpop blpop llen。
lpush lrange rpush
cpp
void test_1(Redis &redis)
{
redis.flushall();
redis.lpush("key","1"); // 单行插入
redis.lpush("key",{"2","3"});
std::vector<std::string> vec{"2","3","4","5"};
redis.lpush("key",vec.begin(), vec.end()); // 迭代器区间插入
std::list<std::string> ans;
auto result = std::front_inserter(ans);
redis.lrange("key", 0, -1, result);
for(auto e : ans)
std::cout << e << " ";
std::cout << std::endl;
}

对于lpush来说,一共有三种push的方式。
第一种是单行插入 ,即我们指定指定一个key,指定插入的元素就可以了。第二种是借助初始化列表 的方式,我们同样指定一个key,然后就像C++11引入的初始化列表那样,一个花括号括起来就行了。第三种方式是使用迭代器的方式,我们任意构建一个可以使用迭代器的容器,比如vector,list,但是如果我们使用的迭代器不对的话,就是有可能报错的。
插入成功之后,我们可以使用lrange进行遍历,遍历的时候,你会发现我使用的迭代器是list的,为什么不使用vector的呢?
我们插入的时候是尾插,那么我是想按照顺序遍历那样给它打印出来,所以博主构建了一个前向迭代器,如果这个时候你使用的是vector,那么很不幸,你是编译不过去的。
因为vector本身是没有头插的方法,list有,所以我们这里只能使用list,到这里,我们也能发现传入迭代器之后,实际上也是通过迭代器来调用container本身的方法,所以这点我们要注意了。
然后这里有一个隐藏的bug,即我们虽然在makefile里面写了-std=c++17,但是你会发现写列表初始化的时候,vscode仍然会报错,但是g++却能正确编译过去。
这个问题的本质其实是因为vscode只是作为一款文本编辑器,g++是一款编译器,g++认makefile,但是vscdoe不认,所以我们需要单独给vscode配置,具体怎么配置,咱这里就不说~~
rpush llen
cpp
void test_2(Redis &redis)
{
redis.flushall();
redis.rpush("key","1");
redis.rpush("key", {"2","3"});
std::vector<std::string> vec{"4","5"};
redis.rpush("key",vec.begin(), vec.end());
std::vector<std::string> ans;
auto result = std::back_inserter(ans);
redis.lrange("key",0, -1, result);
for(auto e : ans)
std::cout << e << " ";
std::cout << std::endl;
long long size = redis.llen("key");
std::cout << "list的长度为: " << size << std::endl;
}

这里我们简单测试一下rpush和llen即可,这两个也没有什么特别要说的,用法和lpush那边一模一样,不过我们注意一下llen的返回值是long long就可以了。
rpop lpop blpop
cpp
void test_3(Redis &redis)
{
redis.flushall();
redis.rpush("key", {"1","2", "3", "4", "5"});
redis.lpop("key");
redis.rpop("key");
std::list<std::string> ans;
auto result = std::back_inserter(ans);
redis.lrange("key", 0, -1, result);
for(auto e : ans)
std::cout << e << " ";
std::cout << std::endl;
}

对于删除,l代表的头删,r代表的尾删,这点也是能够理解的。
对于阻塞的删除,我们也就用一个来演示就可以了,毕竟二者无非就是头删和尾删的区别而已:
cpp
std::optional<std::pair<std::string, std::string>>
Redis::blpop(const std::vector<std::string> &keys, const std::chrono::seconds &timeout);
这是Redis中blpop的原型,我们着重看返回值为optional<std::pair<std::string,string>>,如果没有值,那么返回的就是nil,所以我们需要单独判断一下:
cpp
void test_4(Redis &redis)
{
redis.flushall();
// redis.rpush("key", {"1","2", "3", "4", "5"});
auto ans = redis.blpop("key",10s);
if(ans)
{
std::cout << "key:" << ans->first << std::endl;
std::cout << "ele:" << ans->second << std::endl;
}
else
std::cout << "ans无效" << std::endl;
}

就像这样。
hash
hset hget hmget
对于hash来说,单行插入我们可以直接插入,我们也可以构建一个pair来插入,也可以通过迭代器的方式,插入一个容器的数据,也可以一次性直接插入多个pari。所以它其实已经具备了hmset的功能,那么我们在这里就不展开介绍hmset了。
综上,它的插入方式有四种。
那么hget 的时候,获取到的是optionalString
这里就和之前的string一样了,我们同样需要先判断是否存在该值,然后再结合value函数打印或者使用重载的*打印就可以了。
对于hmget,我们要获取到只需要传入一个vector<string>带出来它的数值就可以了:
cpp
void test_1(Redis &redis)
{
std::cout << "hset hget" << std::endl;
redis.hset("key", {std::make_pair("f1", "111"),
std::make_pair("f2", "222"),
std::make_pair("f3", "333")});
redis.hset("key", "f4", "444");
redis.hset("key", std::make_pair("f5", "555"));
std::vector<std::pair<std::string, std::string>> vec{
std::make_pair("f6", "666"),
std::make_pair("f7", "777"),
std::make_pair("f8", "888")};
redis.hset("key",vec.begin(), vec.end());
auto ans = redis.hget("key", "f6");
if (ans)
std::cout << ans.value() << std::endl;
else
std::cout << "不存在" << std::endl;
std::vector<std::string> res;
auto iter = std::back_inserter(res);
redis.hmget("key", {"f1", "f2", "f5"}, iter);
for(auto e : res)
std::cout << e << " ";
std::cout << std::endl;
}

hkeys hvals hexists
对于hkeys来说,它的作用就是获取所有的fields值,对于hvals来说,它的作用就是获取所有的values,我们只需要用一个容器带出来就可以了。对于hexists就是判断某个fields存不存在就是了。
cpp
void test_2(Redis &redis)
{
redis.flushall();
redis.hset("key", {std::make_pair("f1", "111"),
std::make_pair("f2", "222"),
std::make_pair("f3", "333")});
std::vector<std::string> ans;
auto iter = std::back_inserter(ans);
redis.hkeys("key", iter);
for (auto e : ans)
std::cout << e << " ";
std::cout << std::endl;
redis.hvals("key", iter);
for (auto e : ans)
std::cout << e << " ";
std::cout << std::endl;
bool res = redis.hexists("key", "f1");
if(res) std::cout << "exists!" << std::endl;
else std::cout << "not exists!" << std::endl;
}

hdel
hdel的作用就是用来删除哈希表中的某个field值的,非常好理解
cpp
void test_3(Redis &redis)
{
redis.flushall();
redis.hset("key", {std::make_pair("f1", "111"),
std::make_pair("f2", "222"),
std::make_pair("f3", "333")});
redis.hdel("key", "f2");
std::vector<std::string> ans;
auto iter = std::back_inserter(ans);
redis.hkeys("key", iter);
for(auto e : ans)
std::cout << e << " ";
std::cout << std::endl;
}

其实这篇文章过的这么快的原因主要还是因为在string部分我们已经清楚了对于大多数命令来说可能都需要借助到迭代器,有了这个认识,我们敲起来就非常的迅速了。
那么以上就是list和hash常用命令在Redis-plus-plus中的使用介绍。
感谢阅读!