当前位置: 首页 > news >正文

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.小结

  1. 环境依赖:必须先安装hiredis,再编译redis-plus-plus,编译时需链接三个库:libredis++.a、libhiredis.a、-pthread;
  2. API 特性:redis-plus-plus用OptionalString处理 “可能不存在的值”(如get()),用 “插入迭代器”(back_inserter)处理批量结果(如keys()、lrange());
  3. 异常处理:连接失败、命令错误会抛出异常,需用try-catch捕获(const exception& e);
  4. 代码复用:建议将 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;
}
http://www.dtcms.com/a/430546.html

相关文章:

  • 旅游网站开发文献综述沈阳做网站大约要多少钱
  • 精美个人网站wordpress设置网站主题
  • PyCharm保姆级详细使用手册(Python新手快速上手篇)
  • 3.springboot-容器功能-@注解
  • python开发手机网站开发今天时政新闻热点是什么
  • 【网络编程】深入 HTTP:从报文交互到服务构建,洞悉核心机制
  • java面试0119-java中创建对象的方式?
  • 线程中互斥锁和读写锁相关区别应用示例
  • 网站开发logo绍兴网页设计
  • 2017主流网站风格win7 iis配置网站 视频教程
  • wordpress同步微信公众号seo外包是什么
  • 如何评价一个网站做的好不好展厅网站
  • wordpress站点克隆vip影视建设网站官网
  • 网站免费申请注册软件开发人员犯罪
  • 优秀个人网站设计模板互联网技术发展现状
  • 云南做网站价格网站的策划书
  • 做本地网站要服务器吗自动化毕设题目网站开发
  • 网站后端技术有哪些文学网站做编辑
  • 做淘客应该知道的网站咸阳学校网站建设费用
  • 适合女生做的网站投资公司网站设计
  • 专业网站维护如何免费建立自己的网页
  • 做社交网站的预算怎样查询网站空间
  • 网站重购出行南宁app软件下载
  • html怎么做成网站打开免费百度啊
  • 网站建设的时候如何上传图片如何建设一个个人网站
  • wordpress建设网站的方法怎么查寻一个网站做的竞价
  • 三亚网站制作上海做哪些行业赚钱
  • 静态网站站内搜索网站建设原则应考虑哪些
  • 1688拿货网义乌seo推广
  • 中国十大购物网站排行榜我做网站编辑写文章很慢怎么办