目录
 
  
 
 
0.RESP
 
- RESP:Redis自定义的应用层协议 
   
 - 优点: 
   
 - 工作流程:请求和响应之间的通信模型是一问一答的形式 
  
- 客户端给服务器发一个请求(Redis 命令),服务器返回一个响应
 - 客户端和服务器只需要按照格式,构造出字符串,往
socket中写入或者从socket中读取字符串,按照上述格式解析 
  
 
 
1.前置依赖 – hiredis
 
redis-plus-plus 是基于hiredis实现的,hiredis是⼀个C语⾔实现的Redis客⼾端- 安装:
apt install libhiredis-dev 
 
 
2.安装 redis-plus-plus
 
 
 
3.示例:通用命令
 
1.Quick Start
 
main.cc:#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>
using namespace std;
int main()
{
    
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    string ret = redis.ping();
    cout << ret << endl;
    return 0;
}
 Makefile:main:main.cc
	g++ -std=c++17 -o $@ $^ -l redis++ -l hiredis -l pthread
.PHONY:clean
clean:
	rm main
 
 
 
2.Get && Set
 
- 此处的
redis.get()返回的是一个optional类型 
  optional类型在C++14中,正式纳入标准库- 因为
redis.get()会返回nil无效值,用std::string不方便表现nil,而std::string*虽然可以用nullptr表示无效,但是返回指针又设计内存管理问题 - 所以综上,此处使用
optional表示"非法值"/“无效值” 
 void TestGetAndSet(sw::redis::Redis& redis)
{
	
	redis.flushall();
	
	redis.set("key1", "233");
	redis.set("key2", "666");
	redis.set("key3", "888");
	
	auto value1 = redis.get("key1");
	
	if(value1)
	{
		cout << "value1=" << value1.value() << endl; 
	}
	auto value2 = redis.get("key2");
	if(value2)
	{
		cout << "value2=" << value2.value() << endl;
	}
	auto value3 = redis.get("key3");
	if (value2)
	{
		cout << "value3=" << value3.value() << endl;
	}
	auto value4 = redis.get("key4");
	if (value4)
	{
		
		cout << "value4=" << value4.value() << endl;
	}
}
  
 
 
3.Exists
 
void TestExists(sw::redis::Redis &redis)
{
    redis.flushall();
    redis.set("key1", "111");
    redis.set("key3", "111");
    auto ret = redis.exists("key1");
    cout << ret << endl;
    ret = redis.exists("key2");
    cout << ret << endl;
    
    ret = redis.exists({"key1", "key2", "key3"});
    cout << ret << endl;
}
 
 
4.Keys
 
void TestKeys(sw::redis::Redis &redis)
{
    redis.flushall();
    redis.set("key1", "111");
    redis.set("key2", "222");
    redis.set("key3", "333");
    redis.set("key4", "444");
    redis.set("key5", "555");
    redis.set("key6", "666");
    
    
    
    vector<string> ret;
    auto it = std::back_inserter(ret);
    redis.keys("*", it);
    PrintContainer(ret);
}
 
 
5.Expire && TTL
 
void TestExpireAndTTL(sw::redis::Redis &redis)
{
    redis.flushall();
    redis.set("key", "111");
    
    redis.expire("key", 10s); 
    std::this_thread::sleep_for(3s);
    auto time = redis.ttl("key");
    cout << time << endl;
}
 
 
6.Type
 
void TestType(sw::redis::Redis& redis)
{
    redis.flushall();
    redis.set("key1", "111");
    string result = redis.type("key");
    cout << "key1: " << result << endl;
    redis.lpush("key2", "111");
    result = redis.type("key2");
    cout << "key2: " << result << endl;
    redis.hset("key3", "aaa", "111");
    result = redis.type("key3");
    cout << "key3: " << result << endl;
    redis.sadd("key4", "aaa");
    result = redis.type("key4");
    cout << "key4: " << result << endl;
    redis.zadd("key5", "吕布", 99);
    result = redis.type("key5");
    cout << "key5: " << result << endl;
}
 
 
4.示例:String
 
1.Set with expire
 
void TestSetWithExpire(Redis& redis)
{
    redis.flushall();
    redis.set("key", "111", 10s);
    std::this_thread::sleep_for(3s);
    long long time = redis.ttl("key");
    std::cout << "time: " << time << std::endl;
}
 
 
2.Set NX / XX
 
void TestSetNXAndXX(Redis &redis)
{
    redis.flushall();
    redis.set("key", "111");
    
    
    redis.set("key", "222", 0s, sw::redis::UpdateType::EXIST); 
    auto value = redis.get("key");
    if (value)
    {
        std::cout << "value: " << value.value() << std::endl;
    }
}
 
 
3.Mset
 
void TestMset(Redis &redis)
{
    redis.flushall();
    
    
    
    vector<pair<string, string>> keys = {
        {"key1", "111"},
        {"key2", "222"},
        {"key3", "333"}
    };
    redis.mset(keys.begin(), keys.end());
    auto value = redis.get("key1");
    if (value)
    {
        std::cout << "value: " << value.value() << std::endl;
    }
    value = redis.get("key2");
    if (value)
    {
        std::cout << "value: " << value.value() << std::endl;
    }
    value = redis.get("key3");
    if (value)
    {
        std::cout << "value: " << value.value() << std::endl;
    }
}
 
 
4.Mget
 
void TestMget(Redis &redis)
{
    redis.flushall();
    vector<std::pair<string, string>> keys = {
        {"key1", "111"},
        {"key2", "222"},
        {"key3", "333"}};
    redis.mset(keys.begin(), keys.end());
    vector<sw::redis::OptionalString> result;
    auto it = std::back_inserter(result);
    redis.mget({"key1", "key2", "key3", "key4"}, it);
    PrintContainerOptional(result);
}
 
 
5.Getrange && Setrange
 
void TestRange(Redis &redis)
{
    redis.flushall();
    redis.set("key", "DieKSnowK");
    string result = redis.getrange("key", 2, 5);
    cout << "result: " << result << endl;
    redis.setrange("key", 2, "xyz");
    auto value = redis.get("key");
    cout << "value: " << value.value() << endl;
}
 
 
5.示例:list
 
1.Push && Range
 
void TestPushAndRange(Redis &redis)
{
    redis.flushall();
    
    redis.lpush("key", "111");
    
    redis.lpush("key", {"222", "333", "444"});
    
    vector<string> values = {"555", "666", "777"};
    redis.lpush("key", values.begin(), values.end());
    
    vector<string> results;
    auto it = std::back_inserter(results);
    redis.lrange("key", 0, -1, it);
    PrintContainer(results);
}
 
 
2.Pop
 
void TestPop(Redis &redis)
{
    redis.flushall();
    
    redis.rpush("key", {"1", "2", "3", "4"});
    auto result = redis.lpop("key");
    if (result)
    {
        std::cout << "lpop: " << result.value() << std::endl;
    }
    result = redis.rpop("key");
    if (result)
    {
        std::cout << "rpop: " << result.value() << std::endl;
    }
}
 
 
3.blpop
 
- TIPS:对于
std::optional类型来说,可以直接使用->访问optional内部包含的元素的成员void TestBlpop(Redis &redis)
{
    redis.flushall();
    auto result = redis.blpop({"key", "key2", "key3"}, 10s);
    
    if (result)
    {
        std::cout << "key:" << result->first << std::endl;
        std::cout << "elem:" << result->second << std::endl;
    }
    else
    {
        std::cout << "result 无效!" << std::endl;
    }
}
  
 
 
4.llen
 
void TestLlen(Redis &redis)
{
    redis.flushall();
    redis.lpush("key", {"111", "222", "333", "444"});
    long long len = redis.llen("key");
    cout << "len: " << len << endl;
}
 
 
6.示例:set
 
1.Sadd && Smembers
 
- 此处要注意保存结果的方式和之前的区别
void TestSaddAndSmembers(Redis& redis)
{
    redis.flushall();
    
    redis.sadd("key", "111");
    
    redis.sadd("key", {"222", "333", "444"});
    
    set<string> elems = {"555", "666", "777"};
    redis.sadd("key", elems.begin(), elems.end());
    
    
    
    
    set<string> result;
    
    auto it = std::inserter(result, result.end());
    redis.smembers("key", it);
    PrintContainer(result);
}
  
 
 
2.Sismerber
 
void TestSismember(Redis& redis)
{
    redis.flushall();
    redis.sadd("key", {"111", "222", "333", "444"});
    bool result = redis.sismember("key", "555");
    cout << "result: " << result << endl;
}
 
 
3.Scard
 
void TestScard(Redis &redis)
{
    redis.flushall();
    redis.sadd("key", {"111", "222", "333"});
    long long result = redis.scard("key");
    cout << "result: " << result << endl;
}
 
 
4.Spop
 
void TestSpop(Redis& redis)
{
    redis.flushall();
    redis.sadd("key", {"111", "222", "333", "444"});
    auto result = redis.spop("key");
    if (result)
    {
        std::cout << "result: " << result.value() << std::endl;
    }
    else
    {
        std::cout << "result 无效!" << std::endl;
    }
}
 
 
5.Sinter
 
void TestSinter(Redis &redis)
{
    redis.flushall();
    redis.sadd("key1", {"111", "222", "333"});
    redis.sadd("key2", {"111", "222", "444"});
    set<string> result;
    auto it = std::inserter(result, result.end());
    redis.sinter({"key1", "key2"}, it);
    PrintContainer(result);
}
 
 
6.Sinterstore
 
void TestSinterstore(Redis &redis)
{
    redis.flushall();
    redis.sadd("key1", {"111", "222", "333"});
    redis.sadd("key2", {"111", "222", "444"});
    long long len = redis.sinterstore("key3", {"key1", "key2"});
    cout << "len: " << len << endl;
    set<string> result;
    auto it = std::inserter(result, result.end());
    redis.smembers("key3", it);
    PrintContainer(result);
}
 
 
7.示例:hash
 
1.Hset && Hget
 
void TestHsetAndHget(Redis &redis)
{
    redis.flushall();
    redis.hset("key", "f1", "111");
    redis.hset("key", std::make_pair("f2", "222"));
    
    redis.hset("key", {std::make_pair("f3", "333"),
                       std::make_pair("f4", "444")});
                       
    vector<std::pair<string, string>> fields = {
        std::make_pair("f5", "555"),
        std::make_pair("f6", "666")};
    redis.hset("key", fields.begin(), fields.end());
    auto result = redis.hget("key", "f3");
    if (result)
    {
        std::cout << "result: " << result.value() << std::endl;
    }
    else
    {
        std::cout << "result 无效!" << std::endl;
    }
}
 
 
2.Hexists
 
void TestHexists(Redis &redis)
{
    redis.flushall();
    redis.hset("key", "f1", "111");
    redis.hset("key", "f2", "222");
    redis.hset("key", "f3", "333");
    bool result = redis.hexists("key", "f4");
    std::cout << "result: " << result << std::endl;
}
 
 
3.Hdel
 
void TestHdel(Redis &redis)
{
    redis.flushall();
    redis.hset("key", "f1", "111");
    redis.hset("key", "f2", "222");
    redis.hset("key", "f3", "333");
    long long result = redis.hdel("key", "f1");
    std::cout << "result: " << result << std::endl;
    result = redis.hdel("key", {"f2", "f3"});
    std::cout << "result: " << result << std::endl;
    long long len = redis.hlen("key");
    std::cout << "len: " << len << std::endl;
}
 
 
4.Hkeys && Hvals
 
void TestHkeysAndHvals(Redis &redis)
{
    redis.flushall();
    redis.hset("key", "f1", "111");
    redis.hset("key", "f2", "222");
    redis.hset("key", "f3", "333");
    vector<string> fields;
    auto itFields = std::back_inserter(fields);
    redis.hkeys("key", itFields);
    PrintContainer(fields);
    vector<string> values;
    auto itValues = std::back_inserter(values);
    redis.hvals("key", itValues);
    PrintContainer(values);
}
 
 
5.Hmget && Hmset
 
void TestHmgetAndHmset(Redis &redis)
{
    redis.flushall();
    redis.hmset("key", {std::make_pair("f1", "111"),
                        std::make_pair("f2", "222"),
                        std::make_pair("f3", "333")});
    vector<std::pair<string, string>> pairs = {
        std::make_pair("f4", "444"),
        std::make_pair("f5", "555"),
        std::make_pair("f6", "666")};
    redis.hmset("key", pairs.begin(), pairs.end());
    vector<string> values;
    auto it = std::back_inserter(values);
    redis.hmget("key", {"f1", "f2", "f3"}, it);
    PrintContainer(values);
}
 
 
8.示例:zset
 
1.Zadd && Zrange
 
zrange支持两种主要的风格: 
  - 只查询
member, 不带score - 查询
member同时带score 
 - 关键就是看插入迭代器指向的容器的类型: 
  
- 指向的容器只是包含一个
string, 就是只查询member - 指向的容器包含的是一个
pair, 里面有string和 double, 就是查询member同时带有score 
 void TestZaddAndZrange(Redis &redis)
{
    redis.flushall();
    redis.zadd("key", "吕布", 99);
    redis.zadd("key", {std::make_pair("赵云", 98),
                       std::make_pair("典韦", 97)});
    vector<std::pair<string, double>> members = {
        std::make_pair("关羽", 95),
        std::make_pair("张飞", 93)};
    redis.zadd("key", members.begin(), members.end());
    vector<string> memberResults;
    auto it = std::back_inserter(memberResults);
    redis.zrange("key", 0, -1, it);
    PrintContainer(memberResults);
    vector<std::pair<string, double>> membersWithScore;
    auto it2 = std::back_inserter(membersWithScore);
    redis.zrange("key", 0, -1, it2);
    PrintContainerPair(membersWithScore);
}
  
 
 
2.Zcard
 
void TestZcard(Redis &redis)
{
    redis.flushall();
    redis.zadd("key", "zhangsan", 90);
    redis.zadd("key", "lisi", 91);
    redis.zadd("key", "wangwu", 92);
    redis.zadd("key", "zhaoliu", 93);
    long long result = redis.zcard("key");
    std::cout << "result: " << result << std::endl;
}
 
 
3.Zrem
 
void TestZrem(Redis &redis)
{
    redis.flushall();
    redis.zadd("key", "zhangsan", 90);
    redis.zadd("key", "lisi", 91);
    redis.zadd("key", "wangwu", 92);
    redis.zadd("key", "zhaoliu", 93);
    redis.zrem("key", "zhangsan");
    long long result = redis.zcard("key");
    std::cout << "result: " << result << std::endl;
}
 
 
4.Zscore
 
void TestZscore(Redis &redis)
{
    redis.flushall();
    redis.zadd("key", "zhangsan", 90);
    redis.zadd("key", "lisi", 91);
    redis.zadd("key", "wangwu", 92);
    redis.zadd("key", "zhaoliu", 93);
    auto score = redis.zscore("key", "zhangsan");
    if (score)
    {
        std::cout << "score: " << score.value() << std::endl;
    }
    else
    {
        std::cout << "score 无效" << std::endl;
    }
}