C++ 操作 Redis
1.引言
在 C++ 开发中,redis-plus-plus是操作 Redis 的主流库 —— 它基于hiredis封装,提供了简洁的 C++ 风格 API,支持 Redis 所有核心数据类型与命令。本文将从 “环境安装”“基础连接”“核心命令实操” 三个维度,结合完整代码示例,详细讲解如何用 C++ 操作 Redis。
2.环境搭建
我们这里使用redis-plus-plus 作为C++操作redis的库。
Github 地址
redis-plus-plus是基于hiredis实现的,所以要先装hiredis。
ubuntu环境下:
# 安装hiredis开发包(含头文件与库文件)
sudo apt update
sudo apt install libhiredis-dev
下载redis-plus-plus源码
https://github.com/sewenew/redis-plus-plus.git
先创建一个project目录:
克隆过来
redis-plus-plus 使用cmake作为构建工具(相当于Make file的升级版)
cmake通过程序来生成makefile
创建一个build目录,让编译的临时文件都放到build下,避免污染源代码目录(习惯做法,不是必须)
mkdir build
cd build
使用cmake来编译程序:
发现cmake未安装,进行安装:
apt install cmake
安装好后继续cmake …
之后make进行编译:
下面就是编译生成的内容,主要是.a 和 .so文件,后续代码不一定能找到这里的库,所以可以把库拷贝到系统目录中
把刚才的库拷贝到系统目录:
make install
3. 基础连接:C++ 与 Redis 建立连接
3.1 测试连通性
使用redis-plus-plus连接redis服务器,使用ping命令测试连通性。
vscode连接远程Linux服务器。
编写redis++文件,包含头文件
这里的sw是发布redis的作者名
具体位置可以用find来查找(库文件一般在usr目录下)
#include<> 在系统目录中搜索头文件
#include" " 在项目目录中搜索头文件
创建一个redis对象
进行ping操作
使用makefile编译程序
编译程序的时候,需要引入库文件
1)redis++自己的静态库
2)hiredis 的静态库
3)线程库
更具Linux版本的不同,可能存放在不同的目录下,find查找一下
hello.cc:
#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()
{//创建redis对象的时候,需要在构造函数中指定redis服务器的ip和端口sw::redis::Redis redis("tcp://127.0.0.1:6379");//调用ping方法测试是否连接成功,成功返回PONGcout << "ping: " << redis.ping() << endl;
}
makefile
hello:hello.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17
.PHONY: clean
clean:rm -f hello
3.2 通用命令:get/set/exists/del/keys/expire/type
get,set
这里的参数 和set的选项有很大关系。
C++里string是可修改的。
这里的StringView是只读的(不能修改):针对只读操作,做了很多优化,效率比std::string更高。
Java中的String就是就是类似StringView只读的,要修改要用StringBuilder 或 StringBuffer
C++17标准库中,也提供了一个std::string_view
get的返回值:
此处的optional 可以表示 “非法值” /“无效值”
#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;void test1(sw::redis::Redis &redis)
{cout<<"get 和 set"<<endl;redis.set("name","zhangsan");auto val=redis.get("name"); redis.set("age","20");auto val2=redis.get("age"); cout<<"name:"<<val.value()<<endl;cout<<"age:"<<val2.value()<<endl; redis.flushall();
}int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
.PHONY: all
all: hello generichello:hello.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17generic:generic.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17.PHONY: clean
clean:rm -f hellorm -f generic
exists,del
代码开头清理一下之前的数据
void test2(sw::redis::Redis &redis)
{
cout<<"exists 的使用"<<endl;redis.flushall();redis.set("k1","111");redis.set("k2","222");auto ret1=redis.exists("k1");cout<<"ret1:"<<ret1<<endl;auto ret3=redis.exists("k3");cout<<"ret3:"<<ret3<<endl;auto ret=redis.exists({"k1","k2","k3"});cout<<"ret:"<<ret<<endl;}
void test3(sw::redis::Redis& redis)
{cout<<"del 的使用"<<endl;redis.flushall();redis.set("k1","111");redis.set("k2","222");redis.set("k3","333");auto ret1=redis.del("k1");cout<<"ret1:"<<ret1<<endl; auto ret2=redis.del("k2","k3");cout<<"ret2:"<<ret2<<endl; auto ret3=redis.del("k4");cout<<"ret3:"<<ret3<<endl;}int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");// test1(redis);//test2(redis);test3(redis); return 0;
}
keys
返回多个值
void test4(sw::redis::Redis& redis)
{cout<<"keys 的使用"<<endl; redis.flushall(); redis.set("k1","111"); redis.set("k2","222");redis.set("k3","333");redis.set("k4","444");redis.set("k5","555");//keys的第二个参数是一个“插入迭代器”,我们需要先准备好一个保存结果的容器//再创建一个插入迭代器指向容器的位置,就可以把keys得到的结果通过插入迭代器放入容器的指定位置vector<string> results;auto it = std::back_inserter(results);redis.keys("*",it);for(auto &s:results){cout<<s<<endl;}}int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");// test1(redis);//test2(redis);//test3(redis); test4(redis);return 0;
}
//keys的第二个参数是一个“插入迭代器”,我们需要先准备好一个保存结果的容器
//再创建一个插入迭代器指向容器的位置,就可以把keys得到的结果通过插入
迭代器放入容器的指定位置
STL中五种迭代器的类型:
1.输入迭代器
2.输出迭代器
3.前向迭代器
4.双向迭代器
5.随机访问迭代器
std::sort(beg,end) beg/end—>随机访问迭代器(优势:O(1)访问)
插入迭代器本质也是一种 输出迭代器
通常一个迭代器,主要表示一个位置
插入迭代器则是 位置 + 动作
目的:”解耦合“
expire,ttl
void test5(sw::redis::Redis& redis)
{cout<<"expire 和 ttl"<<endl;redis.flushall();redis.set("k1","111");redis.expire("k1",10); //设置k1的过期时间为10秒auto time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间 }int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");// test1(redis);//test2(redis);//test3(redis); //test4(redis);test5(redis);return 0;
}
void test5(sw::redis::Redis& redis)
{using namespace std::chrono_literals;cout<<"expire 和 ttl"<<endl;redis.flushall();redis.set("k1","111");redis.expire("k1",10); //设置k1的过期时间为10秒auto time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间 std::this_thread::sleep_for(5s);time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间}int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");// test1(redis);//test2(redis);//test3(redis); //test4(redis);test5(redis);return 0;
}
type
void test6(sw::redis::Redis& redis)
{cout<<"type 的使用"<<endl;redis.flushall();redis.set("k1","111");string result= redis.type("k1");cout<<"key:"<<result<<endl;redis.lpush("list1","111");result=redis.type("list1");cout<<"k2:"<<result<<endl;redis.hset("hash1","f1","v1");result=redis.type("hash1");cout<<"k3:"<<result<<endl;redis.sadd("set1","s1");result=redis.type("set1");cout<<"k4:"<<result<<endl;redis.zadd("zset1","m1",100);result=redis.type("zset1");cout<<"k5:"<<result<<endl;
}int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");// test1(redis);//test2(redis);//test3(redis); //test4(redis);// test5(redis);test6(redis);return 0;
}
3.3 String 类型:set/mget/mset/getrange/incr
get,set
string.cc
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<chrono>
#include<thread>
#include<unistd.h>
#include<sw/redis++/redis++.h>
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using sw::redis::Redis;void test1(Redis &redis)
{cout<<"get 和 set"<<endl;redis.flushall();redis.set("k1","111");auto val=redis.get("k1");cout<<"k1:"<<val.value()<<endl;redis.set("k2","222");auto val2=redis.get("k2");cout<<"k2:"<<val2.value()<<endl;}void test2(Redis &redis)
{cout<<"set带有过期时间的使用"<<endl;redis.flushall();redis.set("k1","111",std::chrono::seconds(10)); //设置过期时间为10秒long long time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间std::this_thread::sleep_for(std::chrono::seconds(3));time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间 auto val=redis.get("k1");cout<<"k1:"<<val.value()<<endl;
}int main()
{Redis redis("tcp://127.0.0.1:6379");
//test1(redis);
test2(redis);return 0;
}
makefile
.PHONY: all
all: hello generic stringhello:hello.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17generic:generic.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17string: string.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17.PHONY: clean
clean:rm -f hellorm -f genericrm -f string
void test3(Redis& redis)
{using namespace std::chrono_literals;cout<<"setNX 和 setXX 的使用"<<endl;redis.flushall();redis.set("k1","222",0s,sw::redis::UpdateType::EXIST); //k1不存在,设置成功auto val=redis.get("k1");if(val)cout<<"k1:"<<val.value()<<endl;elsecout<<"k1不存在"<<endl;}
int main()
{Redis redis("tcp://127.0.0.1:6379");
//test1(redis);
//test2(redis);
test3(redis);return 0;
}
mset,mget
void test4(Redis& redis)
{cout<<"mget 和 mset 的使用"<<endl;redis.flushall();vector<std::pair<string,string>> kvs={{"k1","111"},{"k2","222"},{"k3","333"}};redis.mset(kvs.begin(),kvs.end());vector<sw::redis::OptionalString> vals;redis.mget({"k1","k2","k3"},std::back_inserter(vals));for(auto val:vals){if(val)cout<<val.value()<<endl;elsecout<<"不存在"<<endl;}}
int main()
{Redis redis("tcp://127.0.0.1:6379");
//test1(redis);
//test2(redis);
//test3(redis);
test4(redis);return 0;
}
getrange,setrange
void test5(Redis& redis)
{
cout<<"getrange 和 setrange 的使用"<<endl;redis.flushall();redis.set("k1","hello world");auto val=redis.get("k1");cout<<"k1:"<<val.value()<<endl;redis.setrange("k1",6,"redis"); //从下标6开始替换val=redis.get("k1");cout<<"k1:"<<val.value()<<endl;auto sub=redis.getrange("k1",0,4); //获取下标0-4的子串cout<<"sub:"<<sub<<endl;
}int main()
{Redis redis("tcp://127.0.0.1:6379");
//test1(redis);
//test2(redis);
//test3(redis);
//test4(redis);
test5(redis);return 0;
}
incr,decr
incr decr得到的是long long类型
get得到的是optionalString类型 ==》手动转成数字
void test6(Redis& redis)
{
cout<<"incr 和 decr 的使用"<<endl;redis.flushall();redis.set("k","100");auto result =redis.incr("k");cout<<"result:"<<result<<endl;auto value=redis.get("k");cout<<"k:"<<value.value()<<endl;auto result2=redis.decr("k");cout<<"result2:"<<result2<<endl; value=redis.get("k");cout<<"k:"<<value.value()<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");
//test1(redis);
//test2(redis);
//test3(redis);
//test4(redis);
//test5(redis);
test6(redis);return 0;
}
3.4 List 类型:lpush/rpush/lpop/rpop/lrange/blpop
lpush,lrange
list.cc
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<sw/redis++/redis++.h>
using namespace std;
using namespace sw::redis;
using namespace std::chrono_literals;
using std::cout;
using std::endl;void test1(Redis& redis)
{
cout<<"lpush和lrange"<<endl;
redis.flushall();redis.lpush("k1",{"111 ","222 ","333 "});vector<string>value={"aaa ","bbb ","ccc "};
redis.lpush("k1",value.begin(),value.end());vector<string>result;
auto it=std::back_inserter(result);
redis.lrange("k1",0,-1,it);for(auto& v:result)cout<<v<<endl;
}int main()
{Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
rpush,lpop,rpop
void test2(Redis& redis)
{cout<<"rpush"<<endl;redis.flushall();redis.rpush("k1",{"111 ","222 ","333 "});vector<string>value={"aaa ","bbb ","ccc "};redis.rpush("k1",value.begin(),value.end());vector<string>result;auto it=std::back_inserter(result);redis.lrange("k1",0,-1,it);for(auto& v:result)cout<<v<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");//test1(redis);test2(redis);return 0;
}
void test3(Redis& redis)
{cout<<"lpop and rpop"<<endl;redis.flushall();redis.rpush("k1",{"1 ","2 ","3 "});vector<string>value={"a ","b ","c "};redis.rpush("k1",value.begin(),value.end());auto result=redis.lpop("k1");if(result)cout<<*result<<endl;result=redis.rpop("k1");if(result)cout<<*result<<endl; }int main()
{Redis redis("tcp://127.0.0.1:6379");//test1(redis);//test2(redis);test3(redis);return 0;
}
blpop,brpop
返回值:optional里面包含了一个pair,pair里面是string
void test4(Redis& redis)
{cout<<"blpop"<<endl;redis.flushall();auto result=redis.blpop("k1",2s);if(result){cout<<"key:"<<result.value().first<<endl;//result->firstcout<<"elem:"<<result.value().second<<endl;//result->second}elsecout<<"timeout"<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");//test1(redis);//test2(redis);//test3(redis);test4(redis);return 0;
}
llen
void test5(Redis& redis)
{cout<<"llen"<<endl;redis.flushall();redis.rpush("k1",{"1 ","2 ","3 "});auto result=redis.llen("k1");cout<<result<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");//test1(redis);//test2(redis);//test3(redis);//test4(redis);test5(redis);return 0;
}
3.5 Set 类型:sadd/smembers/sismember/spop/sinter
sadd,smembers
set.cc
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<unordered_map>
#include<sw/redis++/redis++.h>using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using sw::redis::Redis;void test1(Redis &redis)
{cout<<"sadd 和 smembers 的使用"<<endl;redis.flushall();redis.sadd("key","111");redis.sadd("key","222");redis.sadd("key",{"333","444","555" });vector<string> elems ={"666","777","888"};redis.sadd("key",elems.begin(),elems.end());std::set<std::string>result;auto it =std::inserter(result,result.end());redis.smembers("key",it);for(auto val:result)cout<<val<<endl;
}int main()
{Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
sismembers,spop,scard
void test2(Redis& redis)
{cout<<"sismember 的使用"<<endl;redis.flushall();redis.sadd("key","111");bool ret =redis.sismember("key","111");if(ret)cout<<"111 is member of key"<<endl;elsecout<<"111 is not member of key"<<endl;cout<<"result:"<<ret<<endl;}
int main()
{Redis redis("tcp://127.0.0.1:6379");// test1(redis);
test2(redis);return 0;
}
void test3(Redis& redis)
{cout<<"scard 的使用"<<endl;redis.flushall();redis.sadd("key","111");redis.sadd("key","222");long long ret =redis.scard("key");cout<<"result:"<<ret<<endl;
}int main()
{Redis redis("tcp://127.0.0.1:6379");// test1(redis);
//test2(redis);
test3(redis); return 0;
}
void test4(Redis& redis)
{cout<<"spop 的使用"<<endl;redis.flushall();redis.sadd("key","111");redis.sadd("key","222");redis.sadd("key","333");auto val =redis.spop("key");if(val)cout<<"poped value:"<<*val<<endl;elsecout<<"key is empty"<<endl;}
sinter,sinterstore
void test5(Redis& redis)
{cout<<"sinter 的使用"<<endl;redis.flushall();redis.sadd("key1","111");redis.sadd("key1","222");redis.sadd("key1","333");redis.sadd("key2","222");redis.sadd("key2","333");redis.sadd("key2","444");std::set<std::string>result;auto it =std::inserter(result,result.end());redis.sinter({"key1","key2"},it);for(auto val:result)cout<<val<<endl;}
void test6(Redis& redis)
{cout<<"sinterstore 的使用"<<endl;redis.flushall();redis.sadd("key1","111");redis.sadd("key1","222");redis.sadd("key1","333");redis.sadd("key2","222");redis.sadd("key2","333");redis.sadd("key2","444");long long len =redis.sinterstore("key3",{"key1","key2"});cout<<"len:"<<len<<endl;std::set<std::string>result;redis.smembers("key3",std::inserter(result,result.end()));for(auto val:result)cout<<val<<endl;}
3.6 Hash 类型:hset/hget/hmset/hmget/hkeys/hvals
hset,hget
hash.cc
void test1(Redis& redis)
{cout<<"hset和hget"<<endl;redis.flushall();redis.hset("key","field1","111");redis.hset("key",std::make_pair("field2","222") );redis.hset("key",{std::make_pair("field3","333"),std::make_pair("field4","444")});vector<std::pair<string,string>>fields={{"field5","555"},{"field6","666"}};redis.hset("key",fields.begin(),fields.end());auto result=redis.hget("key","field3");if(result)cout<<*result<<endl;elsecout<<"no found"<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
hexists,hdel,hlen
void test2(Redis& redis)
{cout<<"hexists"<<endl;redis.flushall();redis.hset("key","field1","111");bool ret=redis.hexists("key","field1");cout<<ret<<endl;ret=redis.hexists("key","field2");cout<<ret<<endl;}
void test3(Redis& redis)
{cout<<"hdel 和hlen"<<endl;redis.flushall();redis.hset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});long long ret=redis.hdel("key",{"field1","field3"});cout<<"ret:"<<ret<<endl;ret=redis.hdel("key",{"field5","field6"});cout<<"ret:"<<ret<<endl;long long len=redis.hlen("key");cout<<"len:"<<len<<endl; }
hkeys,hvals,hmset,hmget
void test4(Redis& redis)
{cout<<"hkeys 和 hvals"<<endl;redis.flushall();redis.hset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});vector<string>fields;auto it=std::back_inserter(fields);redis.hkeys("key",it);for(auto& f:fields)cout<<f<<endl;vector<string>vals;it=std::back_inserter(vals);redis.hvals("key",it);for(auto& v:vals)cout<<v<<endl;}
void test5(Redis& redis)
{cout<<"hmset 和 hmget"<<endl;redis.flushall();redis.hmset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});vector<std::pair<string,string>>fields={std::make_pair("field5","555"),std::make_pair("field6","666")};redis.hmset("key",fields.begin(),fields.end());vector<string>values;auto it=std::back_inserter(values);redis.hmget("key",{"field1","field3","field5"}, it);for(auto& v:values)cout<<v<<endl;}
3.7 Zset 类型:zadd/zrange/zscore/zrank/zrem
zadd zrange
zset.cc
void test1(Redis& redis)
{cout<<"zadd 和 zrange"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33),std::make_pair("member4",44)});vector<std::pair<string,double>>fields={std::make_pair("member5",55),std::make_pair("member6",66)};redis.zadd("key",fields.begin(),fields.end());//通过不同类型的迭代器判断是否获取member时带不带scorevector<string>members;auto it=std::back_inserter(members);redis.zrange("key",0,-1,it);for(auto& m:members)cout<<m<<endl;vector<std::pair<string,double>>membersWithScores;auto it2=std::back_inserter(membersWithScores);redis.zrange("key",0,-1,it2);for(auto& m:membersWithScores)cout<<m.first<<" "<<m.second<<endl;
}
zcard,zrem zscore zrank
void test2(Redis& redis)
{cout<<"zcard"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33),std::make_pair("member4",44)});long long result=redis.zcard("key");cout<<result<<endl;
}
void test3(Redis& redis)
{cout<<"zrem"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33),std::make_pair("member4",44)});long long result=redis.zrem("key",{"member1","member3"});cout<<result<<endl;vector<string>members;auto it=std::back_inserter(members);redis.zrange("key",0,-1,it);for(auto& m:members)cout<<m<<endl;}
void test4(Redis& redis)
{cout<<"zscore"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33),std::make_pair("member4",44)});auto result=redis.zscore("key","member3");if(result)cout<<*result<<endl;elsecout<<"no found"<<endl;}
void test5(Redis& redis)
{cout<<"zrank"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33), std::make_pair("member4",44)});auto result=redis.zrank("key","member3");if(result)cout<<*result<<endl;elsecout<<"no found"<<endl;
}
4.小结
- 环境依赖:必须先安装hiredis,再编译redis-plus-plus,编译时需链接三个库:libredis++.a、libhiredis.a、-pthread;
- API 特性:redis-plus-plus用OptionalString处理 “可能不存在的值”(如get()),用 “插入迭代器”(back_inserter)处理批量结果(如keys()、lrange());
- 异常处理:连接失败、命令错误会抛出异常,需用try-catch捕获(const exception& e);
- 代码复用:建议将 Redis 连接封装为单例类(避免频繁创建连接),按数据类型拆分函数(如test_string()、test_list()),提高代码可读性。
源码
目录结构
makefile
.PHONY: all
all: hello generic string list set hash zsethello:hello.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17generic:generic.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17string: string.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17list: list.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17set: set.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17
hash: hash.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17
zset: zset.ccg++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread -std=c++17.PHONY: clean
clean:rm -f hellorm -f genericrm -f stringrm -f listrm -f setrm -f hashrm -f zset
generic.cc
#include<iostream>
#include<vector>
#include<string>
#include<chrono>
#include<thread>
#include<unistd.h>
#include<unordered_map>
#include<sw/redis++/redis++.h>
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;void test1(sw::redis::Redis &redis)
{cout<<"get 和 set"<<endl;redis.set("name","zhangsan");auto val=redis.get("name"); redis.set("age","20");auto val2=redis.get("age"); cout<<"name:"<<val.value()<<endl;cout<<"age:"<<val2.value()<<endl;
}void test2(sw::redis::Redis &redis)
{
cout<<"exists 的使用"<<endl;redis.flushall();redis.set("k1","111");redis.set("k2","222");auto ret1=redis.exists("k1");cout<<"ret1:"<<ret1<<endl;auto ret3=redis.exists("k3");cout<<"ret3:"<<ret3<<endl;auto ret=redis.exists({"k1","k2","k3"});cout<<"ret:"<<ret<<endl;}void test3(sw::redis::Redis& redis)
{cout<<"del 的使用"<<endl;redis.flushall();redis.set("k1","111");redis.set("k2","222");redis.set("k3","333");auto ret1=redis.del("k1");cout<<"ret1:"<<ret1<<endl; auto ret2=redis.del("k2","k3");cout<<"ret2:"<<ret2<<endl; auto ret3=redis.del("k4");cout<<"ret3:"<<ret3<<endl;}void test4(sw::redis::Redis& redis)
{cout<<"keys 的使用"<<endl; redis.flushall(); redis.set("k1","111"); redis.set("k2","222");redis.set("k3","333");redis.set("k4","444");redis.set("k5","555");//keys的第二个参数是一个“插入迭代器”,我们需要先准备好一个保存结果的容器//再创建一个插入迭代器指向容器的位置,就可以把keys得到的结果通过插入迭代器放入容器的指定位置vector<string> results;auto it = std::back_inserter(results);redis.keys("*",it);for(auto &s:results){cout<<s<<endl;}}void test5(sw::redis::Redis& redis)
{using namespace std::chrono_literals;cout<<"expire 和 ttl"<<endl;redis.flushall();redis.set("k1","111");redis.expire("k1",10); //设置k1的过期时间为10秒auto time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间 std::this_thread::sleep_for(5s);time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间}void test6(sw::redis::Redis& redis)
{cout<<"type 的使用"<<endl;redis.flushall();redis.set("k1","111");string result= redis.type("k1");cout<<"key:"<<result<<endl;redis.lpush("list1","111");result=redis.type("list1");cout<<"k2:"<<result<<endl;redis.hset("hash1","f1","v1");result=redis.type("hash1");cout<<"k3:"<<result<<endl;redis.sadd("set1","s1");result=redis.type("set1");cout<<"k4:"<<result<<endl;redis.zadd("zset1","m1",100);result=redis.type("zset1");cout<<"k5:"<<result<<endl;
}int main()
{sw::redis::Redis redis("tcp://127.0.0.1:6379");// test1(redis);//test2(redis);//test3(redis); //test4(redis);// test5(redis);test6(redis);return 0;
}
string.cc
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<chrono>
#include<thread>
#include<unistd.h>
#include<sw/redis++/redis++.h>
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using sw::redis::Redis;void test1(Redis &redis)
{cout<<"get 和 set"<<endl;redis.flushall();redis.set("k1","111");auto val=redis.get("k1");cout<<"k1:"<<val.value()<<endl;redis.set("k2","222");auto val2=redis.get("k2");cout<<"k2:"<<val2.value()<<endl;}void test2(Redis &redis)
{cout<<"set带有过期时间的使用"<<endl;redis.flushall();redis.set("k1","111",std::chrono::seconds(10)); //设置过期时间为10秒long long time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间std::this_thread::sleep_for(std::chrono::seconds(3));time=redis.ttl("k1");cout<<"time:"<<time<<endl; //打印k1的剩余过期时间 auto val=redis.get("k1");cout<<"k1:"<<val.value()<<endl;
}void test3(Redis& redis)
{using namespace std::chrono_literals;cout<<"setNX 和 setXX 的使用"<<endl;redis.flushall();redis.set("k1","222",0s,sw::redis::UpdateType::EXIST); //k1不存在,设置成功auto val=redis.get("k1");if(val)cout<<"k1:"<<val.value()<<endl;elsecout<<"k1不存在"<<endl;}void test4(Redis& redis)
{cout<<"mget 和 mset 的使用"<<endl;redis.flushall();vector<std::pair<string,string>> kvs={{"k1","111"},{"k2","222"},{"k3","333"}};redis.mset(kvs.begin(),kvs.end());vector<sw::redis::OptionalString> vals;redis.mget({"k1","k2","k3"},std::back_inserter(vals));for(auto val:vals){if(val)cout<<val.value()<<endl;elsecout<<"不存在"<<endl;}}void test5(Redis& redis)
{
cout<<"getrange 和 setrange 的使用"<<endl;redis.flushall();redis.set("k1","hello world");auto val=redis.get("k1");cout<<"k1:"<<val.value()<<endl;redis.setrange("k1",6,"redis"); //从下标6开始替换val=redis.get("k1");cout<<"k1:"<<val.value()<<endl;auto sub=redis.getrange("k1",0,4); //获取下标0-4的子串cout<<"sub:"<<sub<<endl;
}void test6(Redis& redis)
{
cout<<"incr 和 decr 的使用"<<endl;redis.flushall();redis.set("k","100");auto result =redis.incr("k");cout<<"result:"<<result<<endl;auto value=redis.get("k");cout<<"k:"<<value.value()<<endl;auto result2=redis.decr("k");cout<<"result2:"<<result2<<endl; value=redis.get("k");cout<<"k:"<<value.value()<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");
//test1(redis);
//test2(redis);
//test3(redis);
//test4(redis);
//test5(redis);
test6(redis);return 0;
}
list.cc
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<sw/redis++/redis++.h>
using namespace std;
using namespace sw::redis;
using namespace std::chrono_literals;
using std::cout;
using std::endl;void test1(Redis& redis)
{
cout<<"lpush和lrange"<<endl;
redis.flushall();redis.lpush("k1",{"111 ","222 ","333 "});vector<string>value={"aaa ","bbb ","ccc "};
redis.lpush("k1",value.begin(),value.end());vector<string>result;
auto it=std::back_inserter(result);
redis.lrange("k1",0,-1,it);for(auto& v:result)cout<<v<<endl;
}void test2(Redis& redis)
{cout<<"rpush"<<endl;redis.flushall();redis.rpush("k1",{"111 ","222 ","333 "});vector<string>value={"aaa ","bbb ","ccc "};redis.rpush("k1",value.begin(),value.end());vector<string>result;auto it=std::back_inserter(result);redis.lrange("k1",0,-1,it);for(auto& v:result)cout<<v<<endl;}void test3(Redis& redis)
{cout<<"lpop and rpop"<<endl;redis.flushall();redis.rpush("k1",{"1 ","2 ","3 "});vector<string>value={"a ","b ","c "};redis.rpush("k1",value.begin(),value.end());auto result=redis.lpop("k1");if(result)cout<<*result<<endl;result=redis.rpop("k1");if(result)cout<<*result<<endl; }void test4(Redis& redis)
{cout<<"blpop"<<endl;redis.flushall();auto result=redis.blpop({"k1","k2","k3"});if(result){cout<<"key:"<<result.value().first<<endl;cout<<"elem:"<<result.value().second<<endl;}elsecout<<"timeout"<<endl;}void test5(Redis& redis)
{cout<<"llen"<<endl;redis.flushall();redis.rpush("k1",{"1 ","2 ","3 "});auto result=redis.llen("k1");cout<<result<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");//test1(redis);//test2(redis);//test3(redis);//test4(redis);test5(redis);return 0;
}
hash.cc
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<sw/redis++/redis++.h>
using namespace std;
using namespace sw::redis;
using namespace std::chrono_literals;
using std::cout;
using std::endl;void test1(Redis& redis)
{cout<<"hset和hget"<<endl;redis.flushall();redis.hset("key","field1","111");redis.hset("key",std::make_pair("field2","222") );redis.hset("key",{std::make_pair("field3","333"),std::make_pair("field4","444")});vector<std::pair<string,string>>fields={{"field5","555"},{"field6","666"}};redis.hset("key",fields.begin(),fields.end());auto result=redis.hget("key","field3");if(result)cout<<*result<<endl;elsecout<<"no found"<<endl;}void test2(Redis& redis)
{cout<<"hexists"<<endl;redis.flushall();redis.hset("key","field1","111");bool ret=redis.hexists("key","field1");cout<<ret<<endl;ret=redis.hexists("key","field2");cout<<ret<<endl;}void test3(Redis& redis)
{cout<<"hdel 和hlen"<<endl;redis.flushall();redis.hset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});long long ret=redis.hdel("key",{"field1","field3"});cout<<"ret:"<<ret<<endl;ret=redis.hdel("key",{"field5","field6"});cout<<"ret:"<<ret<<endl;long long len=redis.hlen("key");cout<<"len:"<<len<<endl; }void test4(Redis& redis)
{cout<<"hkeys 和 hvals"<<endl;redis.flushall();redis.hset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});vector<string>fields;auto it=std::back_inserter(fields);redis.hkeys("key",it);for(auto& f:fields)cout<<f<<endl;vector<string>vals;it=std::back_inserter(vals);redis.hvals("key",it);for(auto& v:vals)cout<<v<<endl;}void test5(Redis& redis)
{cout<<"hmset 和 hmget"<<endl;redis.flushall();redis.hmset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});vector<std::pair<string,string>>fields={std::make_pair("field5","555"),std::make_pair("field6","666")};redis.hmset("key",fields.begin(),fields.end());vector<string>values;auto it=std::back_inserter(values);redis.hmget("key",{"field1","field3","field5"}, it);for(auto& v:values)cout<<v<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");//test1(redis);
//test2(redis);
//test3(redis);// test4(redis);
test5(redis);return 0;
}
set.cc
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<sw/redis++/redis++.h>
using namespace std;
using namespace sw::redis;
using namespace std::chrono_literals;
using std::cout;
using std::endl;void test1(Redis& redis)
{cout<<"hset和hget"<<endl;redis.flushall();redis.hset("key","field1","111");redis.hset("key",std::make_pair("field2","222") );redis.hset("key",{std::make_pair("field3","333"),std::make_pair("field4","444")});vector<std::pair<string,string>>fields={{"field5","555"},{"field6","666"}};redis.hset("key",fields.begin(),fields.end());auto result=redis.hget("key","field3");if(result)cout<<*result<<endl;elsecout<<"no found"<<endl;}void test2(Redis& redis)
{cout<<"hexists"<<endl;redis.flushall();redis.hset("key","field1","111");bool ret=redis.hexists("key","field1");cout<<ret<<endl;ret=redis.hexists("key","field2");cout<<ret<<endl;}void test3(Redis& redis)
{cout<<"hdel 和hlen"<<endl;redis.flushall();redis.hset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});long long ret=redis.hdel("key",{"field1","field3"});cout<<"ret:"<<ret<<endl;ret=redis.hdel("key",{"field5","field6"});cout<<"ret:"<<ret<<endl;long long len=redis.hlen("key");cout<<"len:"<<len<<endl; }void test4(Redis& redis)
{cout<<"hkeys 和 hvals"<<endl;redis.flushall();redis.hset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});vector<string>fields;auto it=std::back_inserter(fields);redis.hkeys("key",it);for(auto& f:fields)cout<<f<<endl;vector<string>vals;it=std::back_inserter(vals);redis.hvals("key",it);for(auto& v:vals)cout<<v<<endl;}void test5(Redis& redis)
{cout<<"hmset 和 hmget"<<endl;redis.flushall();redis.hmset("key",{std::make_pair("field1","111"),std::make_pair("field2","222"),std::make_pair("field3","333"),std::make_pair("field4","444")});vector<std::pair<string,string>>fields={std::make_pair("field5","555"),std::make_pair("field6","666")};redis.hmset("key",fields.begin(),fields.end());vector<string>values;auto it=std::back_inserter(values);redis.hmget("key",{"field1","field3","field5"}, it);for(auto& v:values)cout<<v<<endl;}int main()
{Redis redis("tcp://127.0.0.1:6379");//test1(redis);
//test2(redis);
//test3(redis);// test4(redis);
test5(redis);return 0;
}
zset.cc
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<sw/redis++/redis++.h>
using namespace std;
using namespace sw::redis;
using namespace std::chrono_literals;
using std::cout;
using std::endl;void test1(Redis& redis)
{cout<<"zadd 和 zrange"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33),std::make_pair("member4",44)});vector<std::pair<string,double>>fields={std::make_pair("member5",55),std::make_pair("member6",66)};redis.zadd("key",fields.begin(),fields.end());//通过不同类型的迭代器判断是否获取member时带不带scorevector<string>members;auto it=std::back_inserter(members);redis.zrange("key",0,-1,it);for(auto& m:members)cout<<m<<endl;vector<std::pair<string,double>>membersWithScores;auto it2=std::back_inserter(membersWithScores);redis.zrange("key",0,-1,it2);for(auto& m:membersWithScores)cout<<m.first<<" "<<m.second<<endl;
}void test2(Redis& redis)
{cout<<"zcard"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33),std::make_pair("member4",44)});long long result=redis.zcard("key");cout<<result<<endl;
}void test3(Redis& redis)
{cout<<"zrem"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33),std::make_pair("member4",44)});long long result=redis.zrem("key",{"member1","member3"});cout<<result<<endl;vector<string>members;auto it=std::back_inserter(members);redis.zrange("key",0,-1,it);for(auto& m:members)cout<<m<<endl;}void test4(Redis& redis)
{cout<<"zscore"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33),std::make_pair("member4",44)});auto result=redis.zscore("key","member3");if(result)cout<<*result<<endl;elsecout<<"no found"<<endl;}void test5(Redis& redis)
{cout<<"zrank"<<endl;redis.flushall();redis.zadd("key",{std::make_pair("member1",11),std::make_pair("member2",22),std::make_pair("member3",33), std::make_pair("member4",44)});auto result=redis.zrank("key","member3");if(result)cout<<*result<<endl;elsecout<<"no found"<<endl;
}int main()
{auto redis=Redis("tcp://127.0.0.1:6379");// test1(redis);
// test2(redis);
// test3(redis);
// test4(redis);
test5(redis);return 0;
}