響應(yīng)式設(shè)計(jì)網(wǎng)站網(wǎng)絡(luò)營(yíng)銷的五大特點(diǎn)
目錄
一、基本介紹
二、認(rèn)識(shí)RESP(redis自定的應(yīng)用層協(xié)議名稱)
三、訪問(wèn)github的技巧
四、安裝redisplusplus
4.1 安裝 hiredis**
4.2 下載 redis-plus-plus 源碼
4.3 編譯/安裝 redis-plus-plus
五、編寫運(yùn)行helloworld
六、redis命令演示
6.1 通用命令的使用
6.2 string的使用
6.3 list的使用
6.4 set的使用
6.5 hash的使用
6.6 zset的使用
redis學(xué)習(xí)🥳
一、基本介紹
在前面的學(xué)習(xí)中主要是學(xué)習(xí) redis 的各種基本操作/命令,都是在 redis 命令行客戶端中手動(dòng)執(zhí)行 redis各種命令,但這種操作方式不是我們?nèi)粘i_(kāi)發(fā)中的主要形式;更多的時(shí)候,我們是使用 redis 的 api 來(lái)實(shí)現(xiàn)定制化的 redis 客戶端程序,進(jìn)一步操作 redis 服務(wù)器;
不管是 redis 提供的命令行客戶端,還是第三方的圖形化客戶端,他們本質(zhì)上都屬于是“通用的客戶端程序”。但相比之下,我們?cè)诠ぷ髦懈M褂玫降氖恰皩S玫摹薄岸ㄖ苹钡目蛻舳顺绦?#xff1b;
二、認(rèn)識(shí)RESP(redis自定的應(yīng)用層協(xié)議名稱)
我們?yōu)槭裁茨芫帉懗鲆粋€(gè)自定義的redis客戶端呢?
我們知道在網(wǎng)絡(luò)通信過(guò)程中,會(huì)使用到很多的“協(xié)議”
應(yīng)用層往下的協(xié)議是固定好的,是在系統(tǒng)內(nèi)核或者驅(qū)動(dòng)程序中實(shí)現(xiàn)的,我們是不可修改的,但是對(duì)于應(yīng)用層來(lái)說(shuō),雖然業(yè)界有很多成熟的應(yīng)用層協(xié)議,比如 http 等,但是此處更多的時(shí)候,都會(huì)“自定義”應(yīng)用層協(xié)議,redis 此處應(yīng)用層協(xié)議,就是自定義的應(yīng)用層協(xié)議,客戶端按照 resp 協(xié)議發(fā)送請(qǐng)求,服務(wù)器按照這個(gè)協(xié)議進(jìn)行解析,在按照這個(gè)協(xié)議構(gòu)造響應(yīng),客戶端在解析這個(gè)響應(yīng),完成客戶端和服務(wù)器的通信;
因此:resp 就是 redis 自定義的客戶端和服務(wù)器用于通信的應(yīng)用層協(xié)議;
resp協(xié)議特點(diǎn):
- 簡(jiǎn)單好實(shí)現(xiàn);
- 快速進(jìn)行解析;
- 肉眼可讀;
- 基于傳輸層的tcp,但是與tcp又沒(méi)有強(qiáng)耦合;
- 請(qǐng)求和響應(yīng)之間的通信是一問(wèn)一答的形式(客戶端給服務(wù)器發(fā)起一個(gè)請(qǐng)求,服務(wù)器返回一個(gè)響應(yīng));
- 客戶端給redis服務(wù)器發(fā)送命令時(shí):是以bulk string數(shù)組的形式發(fā)送的redis命令,對(duì)于不同的redis命令,服務(wù)器返回的結(jié)果是不一樣的(ok、整個(gè)數(shù)組...);
在RESP中,第一個(gè)字節(jié)決定了數(shù)據(jù)類型:
- 對(duì)于Simple Strings,回復(fù)的第一個(gè)字節(jié)是“+” eg:"+OK\r\n"
- 對(duì)于Errors,回復(fù)的第一個(gè)字節(jié)是“-” ? eg:"-Error message\r\n"
- 對(duì)于Integers,回復(fù)的第一個(gè)字節(jié)是“:” ? eg:":1000\r\n"
- 對(duì)于Bulk Strings,回復(fù)的第一個(gè)字節(jié)是“$” ? eg:"$5\r\nhello\r\n"
- 對(duì)于Arrays,回復(fù)的第一個(gè)字節(jié)是“*” ? eg:"*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n"
在進(jìn)行通信的時(shí)候,服務(wù)器就把構(gòu)造好的字符串,寫入到 tcp socket 中;
Simple Strings 和 Bulk Strings 的區(qū)別:Simple String 只能用來(lái)傳輸文本,Bulk String 可以傳輸二進(jìn)制數(shù)據(jù);
上述這套協(xié)議公開(kāi)已久,已經(jīng)有很多大佬,實(shí)現(xiàn)了這套協(xié)議的解析/構(gòu)造,在寫代碼的時(shí)候,我們不需要按照上述的協(xié)議,解析/構(gòu)造字符串,只要使用這些大佬們提供的庫(kù),就可以比較簡(jiǎn)單方便的來(lái)完成和 redis 服務(wù)器通信的操作了;
三、訪問(wèn)github的技巧
翻墻 or 下載游戲加速器,推薦:watt toolkit
選中g(shù)itup,一鍵加速
四、安裝redisplusplus
C++ 操作 redis 的庫(kù)有很多,咱們此處使用 redis-plus-plus.
這個(gè)庫(kù)的功能強(qiáng)大,使用簡(jiǎn)單.
Github 地址: ?https://github.com/sewenew/redis-plus-plus
4.1 安裝 hiredis**
redis-plus-plus 是基于 hiredis 實(shí)現(xiàn)的.
hiredis 是一個(gè) C 語(yǔ)言實(shí)現(xiàn)的 redis 客戶端.
因此需要先安裝 hiredis. 直接使用包管理器安裝即可.
在 Ubuntu 鏡像下:
apt install libhiredis-dev
4.2 下載 redis-plus-plus 源碼
git clone https://github.com/sewenew/redis-plus-plus.git
4.3 編譯/安裝 redis-plus-plus
redis-plus-plus 是使用 cmake 構(gòu)建工具進(jìn)行構(gòu)建的,cmake 相當(dāng)于是 Makefile 的升級(jí)版,Makefile 本身功能比較簡(jiǎn)陋,比較原始,寫起來(lái)也比較麻煩實(shí)際開(kāi)發(fā)中很少會(huì)手寫 makefile,cmake 就是通過(guò)程序來(lái)生成 makefile 的 工具;
在 Ubuntu 鏡像下:
使用 cmake 構(gòu)建:
cd redis-plus-plus# 創(chuàng)建一個(gè) build 目錄是習(xí)慣做法,并非必須。目的是為了讓編譯生成的臨時(shí)文件都放到 build 下,避免污染源代碼目錄
mkdir build
cd build# 這個(gè)操作是生成makefile,此處..指向的是剛才 CMakeLits.txt 文件所在的目錄
cmake3 ..make ? ?# 進(jìn)行編譯
sudo make install # 將編譯生成的 .a .so 等系列庫(kù)拷貝到系統(tǒng)目錄
make 后結(jié)果:
make install 后結(jié)果:
構(gòu)建成功后,會(huì)在 /usr/local/include/ 中多出 sw 目錄,并且內(nèi)部包含 redis-plus-plus 的一系列頭文件;
會(huì)在 /usr/local/lib/ 中多出一系列 libredis 庫(kù)文件.
五、編寫運(yùn)行helloworld
創(chuàng)建代碼目錄:
編寫 hello.cpp 文件:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sw/redis++/redis++.h>using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;int main() {// 創(chuàng)建 Redis 對(duì)象的時(shí)候,需要在構(gòu)造函數(shù)中指定 redis 服務(wù)器地址和端口;sw::redis::Redis redis("tcp://127.0.0.1:6379");// 使用 ping 方法,讓客戶端給服務(wù)器發(fā)送了一個(gè) PING,然后服務(wù)器就會(huì)返回一個(gè) PONG,通過(guò)返回值獲取的string result = redis.ping();cout << result << endl;
}
編寫 makefile 文件:
hello:hello.cppg++ -std=c++17 -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread# /usr/local/lib/libredis++.a ? ? ? ? ? ?? ?redis自己的靜態(tài)庫(kù)# /usr/lib/x86_64-linux-gnu/libhiredis.a ? ?hiredis的靜態(tài)庫(kù)# -pthread?? ??? ??? ??? ??? ??? ??? ??? ??? ?線程庫(kù).PHONY:clean
clean:rm hello
編譯運(yùn)行:
六、redis命令演示
工具文件:
util.hpp 文件:
# pragma once# include <iostream>
# include <vector>
#include <string>// 打印容器內(nèi)元素
template<typename T>
inline void printContainer(const T& container) {for(const auto& elem : container) {std::cout << elem << std::endl;}
}// 當(dāng)容器內(nèi)元素是 pair 類型時(shí),打印容器內(nèi)元素
template<typename T>
inline void printContainerPair(const T& container) {for(const auto& elem : container) {std::cout << elem.first << " : " << elem.second << std::endl;}
}// 當(dāng)容器內(nèi)元素是 optional 類型時(shí),打印容器內(nèi)元素
template<typename T>
inline void printContainerOptional(const T& container) {for(const auto& elem : container) {if(elem) {std::cout << elem.value() << std::endl;} else {std::cout << "元素?zé)o效" << std::endl;}}
}
6.1 通用命令的使用
genetric.cpp 文件:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <chrono>
#include <thread>
#include <sw/redis++/redis++.h>#include "util.hpp"using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using sw::redis::Redis;// get 和 set 的使用
void test1(Redis& redis) {cout << "get 和 set 的使用" << endl;// 清空數(shù)據(jù)庫(kù),避免之前殘留的數(shù)據(jù)有干擾redis.flushall();// 使用 set 設(shè)置 keyredis.set("key1", "111");redis.set("key2", "222");redis.set("key3", "333");// 使用 get 獲取到 key 對(duì)應(yīng)的 valueauto value1 = redis.get("key1");if(value1) {cout << "value1 = " << value1.value() << endl;} else {cout << "當(dāng)前 key 不存在" << endl;}auto value2 = redis.get("key2");if(value2) {cout << "value2 = " << value2.value() << endl;} else {cout << "當(dāng)前 key 不存在" << endl;}auto value3 = redis.get("key3");if(value3) {cout << "value3 = " << value3.value() << endl;} else {cout << "當(dāng)前 key 不存在" << endl;}auto value4 = redis.get("key4");if(value4) {cout << "value4 = " << value4.value() << endl;} else {cout << "當(dāng)前 key 不存在" << endl;}
}// exists 的使用
void test2(Redis& redis) {cout << "exists" << endl;redis.flushall();redis.set("key", "111");redis.set("key3", "111");auto ret = redis.exists("key");cout << ret << endl;ret = redis.exists("key2");cout << ret << endl;ret = redis.exists({"key1", "key2", "key3"});cout << ret << endl;
}// del 的使用
void test3(Redis& redis) {cout << "del" << endl;redis.flushall();redis.set("key1", "111");redis.set("key2", "222");vector<string> input{"key1", "key2", "key3"};auto ret = redis.del(input.begin(), input.end());cout << ret << endl;ret = redis.exists({"key1", "key2"});cout << ret << endl;
}// keys 的使用
void test4(Redis& redis) {cout << "keys" << endl;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");// keys 的第二個(gè)參數(shù)是一個(gè)“插入迭代器”,咱們需要先準(zhǔn)備好一個(gè)保存結(jié)果的容器// 接下來(lái)再創(chuàng)建一個(gè)插入迭代器指向容器的位置. 就可以把 keys 獲取到的結(jié)果依次通過(guò)剛才的插入迭代器插入到容器的指定位置中了.vector<string> result;auto it = std::back_inserter(result);redis.keys("*", it);printContainer(result);
}void test5(Redis& redis) {using namespace std::chrono_literals;std::cout << "expire and ttl" << std::endl;redis.flushall();redis.set("key", "111");// 10s => std::chrono::seconds(10)redis.expire("key", 10s);std::this_thread::sleep_for(3s);auto time = redis.ttl("key");std::cout << time << std::endl;
}void test6(sw::redis::Redis& redis) {std::cout << "type" << std::endl;redis.flushall();redis.set("key", "111");string result = redis.type("key");std::cout << "key: " << result << std::endl;redis.lpush("key2", "111");result = redis.type("key2");std::cout << "key2: " << result << std::endl;redis.hset("key3", "aaa", "111");result = redis.type("key3");std::cout << "key3: " << result << std::endl;redis.sadd("key4", "aaa");result = redis.type("key4");std::cout << "key4: " << result << std::endl;redis.zadd("key5", "呂布", 99);result = redis.type("key5");std::cout << "key5: " << result << std::endl;
}int main() {Redis redis("tcp://127.0.0.1:6379");// test1(redis);// test2(redis);// test3(redis);// test4(redis);// test5(redis);test6(redis);
}
get 和 set:test1()結(jié)果:
exists:test2()結(jié)果:
del:test3()結(jié)果:
keys:test4()結(jié)果:
expire and ttl:test5()結(jié)果:
type:test6()結(jié)果:
6.2 string的使用
string.cpp 文件:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <chrono>
#include <thread>#include <sw/redis++/redis++.h>
#include "util.hpp"using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;using sw::redis::Redis;using namespace std::chrono_literals;void test1(Redis& redis) {std::cout << "get 和 set" << std::endl;redis.flushall();redis.set("key", "111");auto value = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;}redis.set("key", "222");value = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;}
}void test2(Redis& redis) {std::cout << "set 帶有超時(shí)時(shí)間" << std::endl;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;
}void test3(Redis& redis) {std::cout << "set NX 和 XX" << std::endl;redis.flushall();redis.set("key", "111");// set 的重載版本中, 沒(méi)有單獨(dú)提供 NX 和 XX 的版本, 必須搭配過(guò)期時(shí)間的版本來(lái)使用. redis.set("key", "222", 0s, sw::redis::UpdateType::EXIST);auto value = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;} else {std::cout << "key 不存在!" << std::endl;}
}void test4(Redis& redis) {std::cout << "mset" << std::endl;redis.flushall();// 第一種寫法, 使用初始化列表描述多個(gè)鍵值對(duì)// redis.mset({ std::make_pair("key1", "111"), std::make_pair("key2", "222"), std::make_pair("key3", "333") });// 第二種寫法, 可以把多個(gè)鍵值對(duì)提前組織到容器中. 以迭代器的形式告訴 msetvector<std::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;}
}void test5(Redis& redis) {std::cout << "mget" << std::endl;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);
}void test6(Redis& redis) {std::cout << "getrange 和 setrange" << std::endl;redis.flushall();redis.set("key", "abcdefghijk");string result = redis.getrange("key", 2, 5);std::cout << "result: " << result << std::endl;redis.setrange("key", 2, "xyz");auto value = redis.get("key");std::cout << "value: " << value.value() << std::endl;
}void test7(Redis& redis) {std::cout << "incr 和 decr" << std::endl;redis.flushall();redis.set("key", "100");long long result = redis.incr("key");std::cout << "result: " << result << std::endl;auto value = redis.get("key");std::cout << "value: " << value.value() << std::endl;result = redis.decr("key");std::cout << "result: " << result << std::endl;value = redis.get("key");std::cout << "value: " << value.value() << std::endl;
}int main() {Redis redis("tcp://127.0.0.1:6379");// test1(redis);// test2(redis);// test3(redis);// test4(redis);// test5(redis);// test6(redis);test7(redis);return 0;
}
get 和 set:test1()結(jié)果:
set 帶有超時(shí)時(shí)間:test2()結(jié)果:
set NX 和 XX:test3()結(jié)果:
mset 帶有超時(shí)時(shí)間:test4()結(jié)果:
mget 帶有超時(shí)時(shí)間:test5()結(jié)果:
getrange 和 setrange 帶有超時(shí)時(shí)間:test6()結(jié)果:
incr 和 dec 帶有超時(shí)時(shí)間:test7()結(jié)果:
6.3 list的使用
list.cpp 文件:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <thread>
#include <chrono>
#include <sw/redis++/redis++.h>
#include "util.hpp"using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using sw::redis::Redis;using namespace std::chrono_literals;void test1(Redis& redis) {std::cout << "lpush 和 lrange" << std::endl;redis.flushall();// 插入單個(gè)元素redis.lpush("key", "111");// 插入一組元素, 基于初始化列表redis.lpush("key", {"222", "333", "444"});// 插入一組元素, 基于迭代器vector<string> values = {"555", "666", "777"};redis.lpush("key", values.begin(), values.end());// lrange 獲取到列表中的元素vector<string> results;auto it = std::back_inserter(results);redis.lrange("key", 0, -1, it);printContainer(results);
}void test2(Redis& redis) {std::cout << "rpush" << std::endl;redis.flushall();// 插入單個(gè)元素redis.rpush("key", "111");// 插入多個(gè)元素, 基于初始化列表redis.rpush("key", {"222", "333", "444"});// 插入多個(gè)元素, 基于容器vector<string> values = {"555", "666", "777"};redis.rpush("key", values.begin(), values.end());// 使用 lrange 獲取元素vector<string> results;auto it = std::back_inserter(results);redis.lrange("key", 0, -1, it);printContainer(results);
}void test3(Redis& redis) {std::cout << "lpop 和 rpop" << std::endl;redis.flushall();// 構(gòu)造一個(gè) listredis.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;}
}void test4(Redis& redis) {using namespace std::chrono_literals;std::cout << "blpop" << std::endl;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 無(wú)效!" << std::endl;}
}void test5(Redis& redis) {std::cout << "llen" << std::endl;redis.flushall();redis.lpush("key", {"111", "222", "333", "444"});long long len = redis.llen("key");std::cout << "len: " << len << std::endl;
}int main() {Redis redis("tcp://127.0.0.1:6379");// test1(redis);// test2(redis);// test3(redis);// test4(redis);test5(redis);return 0;
}
lpush 和 lrange:test1()結(jié)果:
rpush:test2()結(jié)果:
lpop 和 rpo:test3()結(jié)果:
blpop:test4()結(jié)果:
llen:test5()結(jié)果:
6.4 set的使用
set.cpp 文件:
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <unordered_map>
#include <sw/redis++/redis++.h>#include "util.hpp"using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using std::set;using sw::redis::Redis;void test1(Redis& redis) {std::cout << "sadd 和 smembers" << std::endl;redis.flushall();// 一次添加一個(gè)元素redis.sadd("key", "111");// 一次添加多個(gè)元素(使用初始化列表)redis.sadd("key", {"222", "333", "444"});// 一次添加多個(gè)元素(使用迭代器)set<string> elems = {"555", "666", "777"};redis.sadd("key", elems.begin(), elems.end());// 獲取到上述元素// 此處用來(lái)保存 smembers 的結(jié)果, 使用 set 可能更合適. vector<string> result;// auto it = std::back_inserter(result);// 由于此處 set 里的元素順序是固定的. 指定一個(gè) result.end() 或者 result.begin() 或者其他位置的迭代器, 都無(wú)所謂~~auto it = std::inserter(result, result.end());redis.smembers("key", it);printContainer(result);
}void test2(Redis& redis) {std::cout << "sismember" << std::endl;redis.flushall();redis.sadd("key", {"111", "222", "333", "444"});bool result = redis.sismember("key", "555");std::cout << "result: " << result << std::endl;
}void test3(Redis& redis) {std::cout << "scard" << std::endl;redis.flushall();redis.sadd("key", {"111", "222", "333"});long long result = redis.scard("key");std::cout << "result: " << result << std::endl;
}void test4(Redis& redis) {std::cout << "spop" << std::endl;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 無(wú)效!" << std::endl;}
}void test5(Redis& redis) {std::cout << "sinter" << std::endl;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);
}void test6(Redis& redis) {std::cout << "sinterstore" << std::endl;redis.flushall();redis.sadd("key1", {"111", "222", "333"});redis.sadd("key2", {"111", "222", "444"});long long len = redis.sinterstore("key3", {"key1", "key2"});std::cout << "len: " << len << std::endl;set<string> result;auto it = std::inserter(result, result.end());redis.smembers("key3", it);printContainer(result);
}int main() {Redis redis("tcp://127.0.0.1:6379");// test1(redis);// test2(redis);// test3(redis);// test4(redis);// test5(redis);test6(redis);return 0;
}
sadd 和 smembers:test1()結(jié)果:
sismember:test2()結(jié)果:
scard:test3()結(jié)果:
spop:test4()結(jié)果:
sinter:test5()結(jié)果:
sinterstore:test6()結(jié)果:
6.5 hash的使用
hash.cpp 文件:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sw/redis++/redis++.h>#include "util.hpp"using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;using sw::redis::Redis;void test1(Redis& redis) {std::cout << "hset 和 hget" << std::endl;redis.flushall();redis.hset("key", "f1", "111");redis.hset("key", std::make_pair("f2", "222"));// hset 能夠一次性插入多個(gè) field-value 對(duì)!!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 無(wú)效!" << std::endl;}
}void test2(Redis& redis) {std::cout << "hexits" << std::endl;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;
}void test3(Redis& redis) {std::cout << "hdel" << std::endl;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;
}void test4(Redis& redis) {std::cout << "hkeys 和 hvals" << std::endl;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);
}void test5(Redis& redis) {std::cout << "hmget 和 hmset" << std::endl;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);
}int main() {Redis redis("tcp://127.0.0.1:6379");// test1(redis);// test2(redis);// test3(redis);// test4(redis);test5(redis);return 0;
}
hset 和 hget:test1()結(jié)果:
hexits:test2()結(jié)果:
hdel:test3()結(jié)果:
hkeys 和 hvals:test4()結(jié)果:
hmget 和 hmset:test5()結(jié)果:
6.6 zset的使用
zset.cpp 文件:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sw/redis++/redis++.h>#include "util.hpp"using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;using sw::redis::Redis;void test1(Redis& redis) {std::cout << "zadd 和 zrange" << std::endl;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("關(guān)羽", 95),std::make_pair("張飛", 93)};redis.zadd("key", members.begin(), members.end());// zrange 支持兩種主要的風(fēng)格:// 1. 只查詢 member, 不帶 score// 2. 查詢 member 同時(shí)帶 score// 關(guān)鍵就是看插入迭代器指向的容器的類型. // 指向的容器只是包含一個(gè) string, 就是只查詢 member// 指向的容器包含的是一個(gè) pair, 里面有 string 和 double, 就是查詢 member 同時(shí)帶有 scorevector<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);
}void test2(Redis& redis) {std::cout << "zcard" << std::endl;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;
}void test3(Redis& redis) {std::cout << "zrem" << std::endl;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;
}void test4(Redis& redis) {std::cout << "zscore" << std::endl;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 無(wú)效" << std::endl;}
}void test5(Redis& redis) {std::cout << "zrank" << std::endl;redis.flushall();redis.zadd("key", "zhangsan", 90);redis.zadd("key", "lisi", 91);redis.zadd("key", "wangwu", 92);redis.zadd("key", "zhaoliu", 93);auto rank = redis.zrank("key", "zhaoliu");if (rank) {std::cout << "rank: " << rank.value() << std::endl;} else {std::cout << "rank 無(wú)效" << std::endl;}
}int main() {Redis redis("tcp://127.0.0.1:6379");// test1(redis);// test2(redis);// test3(redis);// test4(redis);test5(redis);return 0;
}
zadd 和 zrange:test1()結(jié)果:
zcard:test2()結(jié)果:
zrem:test3()結(jié)果:
zscore:test4()結(jié)果:
zrank:test5()結(jié)果:
redis學(xué)習(xí)打卡🥳