C++与Redis高效交互:通过optional与迭代器玩转String/List/Set......,打造高性能存储方案!

文章目录

本篇摘要

本文详细介绍了C++通过redis-plus-plus操作Redis的完整流程,涵盖String、List、Set、Hash、Zset等数据类型的常用命令(如set/getmset/mgetsadd/spophset/hgetzadd/zrange等),结合std::optional、迭代器等C++特性解析参数传递、返回值处理及无效值管理,并提供完整测试代码,助力开发者快速掌握Redis C++客户端开发。

一.C++之Redis客户端 String基础操作

1.String的nx及xx选项

测试代码:

cpp 复制代码
void test_nx_xx(Redis &redis)
{

    redis.flushall();
    auto ok1 = redis.set("key1", "val1", std::chrono::seconds(0), sw::redis::UpdateType::NOT_EXIST);
    if (redis.get("key1").has_value())
        cout << ok1 << " :" << redis.get("key1").value() << endl;
    auto ok2 = redis.set("key1", "vals", std::chrono::seconds(0), sw::redis::UpdateType::EXIST);
    if (redis.get("key1").has_value())
        cout << ok2 << " :" << redis.get("key1").value() << endl;
}

效果:

注意:这里的关于秒数必须要填,其次就是更新类型。

2.String的expires与ttl选项

测试代码:

cpp 复制代码
void test_expire_ttl(Redis &redis)
{
    using namespace std::chrono_literals;
    redis.flushall();
    auto ok1 = redis.set("key1", "val1", std::chrono::seconds(9), sw::redis::UpdateType::NOT_EXIST);
    // redis.expire("key1",2ms);
    std::this_thread::sleep_for(2s);
    cout << "剩余时间: " << redis.ttl("key1") << endl;
}

测试效果:

注:多种写法。

3.String的mset与megt选项

测试代码:

cpp 复制代码
void test_mset_mmget(Redis &redis)
{
    redis.flushall();
    // redis.mset({{"key1", "val1"},{"key2","val2"}}); 编译无法识别
    // 或者也可以搞个容器,传进去:
    redis.mset({std::make_pair("key1", "val1"), std::make_pair("key2", "val2")});

    vector<sw::redis::OptionalString> v;
    auto bt = std::back_inserter(v);
    redis.mget({"key1", "key2", "key3"}, bt);
    printoptional(v);
}

测试效果:

注:这里给mget传进去的是optionalString数组,构建后插迭代器需要注意。

4.String的incr与decr选项

测试代码:

cpp 复制代码
void test_inct_decr(Redis &redis)
{

    redis.flushall();
    auto ok1 = redis.set("key1", "2");
    cout << redis.get("key1").value() << endl;
    redis.incr("key1");
    cout << redis.get("key1").value() << endl;
    redis.decr("key1");
    cout << redis.get("key1").value() << endl;
}

测试效果:

注:对应的value一定是要数字字符串。

5.String的getrange与setrange选项

测试代码:

cpp 复制代码
void test_getrange_setrange(Redis&redis){
    redis.flushall();

   redis.setrange("key1",2,"2222");
  cout<< redis.getrange("key1",1,10)<<endl;
}

测试效果:

注:如果不是覆盖式,则跳过此位置,不插入,get的时候获得的是无不是空位串。

测试总代码

点我速看

二.C++之Redis客户端 List基础操作

1.List的lpush rpush及lpop rpop lange选项

测试效果:

测试代码:

cpp 复制代码
void test_lrpush_lrpop(Redis&redis){

    redis.flushall();
    redis.lpush("key1",{"1","2","3"});//这里第二个参数也重载了迭代器区间。
    redis.rpush("key1",{"4","5","6"});//这里第二个参数也重载了迭代器区间。
//321456
    vector<string> v;
    auto bt=std::back_inserter(v);
    redis.lrange("key1",0,5,bt);
    print(v);
    redis.rpop("key1");
    redis.lpop("key1");
    //2145
    v.clear();//这里back_inserter,尾插指向的是当前v的后一个位置,故需要及时清除。
    bt=std::back_inserter(v);
    redis.lrange("key1",0,5,bt);
    print(v);
}
2.List的llen选项

测试效果:

测试代码:

cpp 复制代码
void test_llen(Redis&redis){
    redis.flushall();
    redis.lpush("key1",{"1","2","3"});//这里第二个参数也重载了迭代器区间。
    redis.rpush("key1",{"4","5","6"});//这里第二个参数也重载了迭代器区间。

   cout<<"总长度:"<< redis.llen("key1")<<endl;
      vector<string> v;
    auto bt=std::back_inserter(v);
    redis.lrange("key1",0,10,bt);
    print(v);
   
}
3.List的blpop brpop选项

测试效果:

开始阻塞:

进行头插:

进行尾插:

测试代码:

cpp 复制代码
void test_blpop_brpop(Redis&redis){
     redis.flushall();
   cout<<"开始阻塞获取"<<endl;
   auto ret= redis.blpop({"key2","key1"});
   cout<<"list: "<<ret.value().first<<" val: "<<ret->second;
      cout<<"开始阻塞获取"<<endl;
    ret= redis.brpop({"key3"});
   cout<<"list: "<<ret.value().first<<" val: "<<ret->second;
}

测试总代码

点我速看

三.C++之Redis客户端 Set基础操作

1.Set的sadd spop及smembers scard选项

测试效果:

测试代码:

cpp 复制代码
void test_sadd_smembers_scard_spop(Redis &redis)
{

    redis.flushall();

    redis.sadd("key1", {"1", "2", "3"}); // 这里也可以是迭代器区间
    std::unordered_set<string> us;
    auto i = std::inserter(us, us.end()); // 这里需要用它,不能是back_inserter,因为set对应的进行迭代器插入调用的是insert,不是push_back(防止报错)
    redis.smembers("key1", i);
    print(us);
    cout << "个数:" << redis.scard("key1") << endl;
 
        cout << "spop结果: " << redis.spop("key1").value() << endl;
    cout << "个数:" << redis.scard("key1") << endl;
}

注:见注释。

2.Set的集合操作

测试效果:


测试代码:

cpp 复制代码
void test_sinter_sunion_sdiff_store(Redis &redis)
{
    redis.flushall();

    redis.sadd("key1", {"1", "2", "3"}); // 这里也可以是迭代器区间
    redis.sadd("key2", {"1", "2", "4"}); // 这里也可以是迭代器区间

    std::unordered_set<string> us;
    auto i = std::inserter(us, us.end()); // 这里需要用它,不能是back_inserter,因为set对应的进行迭代器插入调用的是insert,不是push_back(防止报错)
    redis.sinter({"key1", "key2"}, i);
    cout << "交集: " << endl;
    print(us);
    us.clear();
    i = std::inserter(us, us.end()); // 指向末尾
    redis.sunion({"key1", "key2"}, i);
    cout << "并集: " << endl;
    print(us);

    us.clear();
    i = std::inserter(us, us.end()); // 指向末尾
    redis.sdiff({"key1", "key2"}, i);
    cout << "差集: " << endl;
    print(us);

    redis.sinterstore("des1", {"key1", "key2"});
    redis.sunionstore("des2", {"key1", "key2"});
    redis.sdiffstore("des2", {"key1", "key2"});
}

测试总代码

点我速看

四.C++之Redis客户端 Hash基础操作

1.Hash的hset hget hdel exists选项

测试效果:

测试代码:

cpp 复制代码
void test_hset_hget_hdel_exists(Redis &redis)
{

    redis.flushall();

    redis.hset("key1", {std::make_pair("1", "2"), std::make_pair("2", "3")}); // 也可以pair类型迭代器
    cout << "个数: " << redis.exists("key1") << endl;
    cout << redis.hget("key1", "1").value() << endl;
    redis.hdel("key1", "1");
    cout << "个数: " << redis.exists("key1") << endl;
}
2.Hash的hmset hmget hkeys hvals选项

测试效果:

测试代码:

cpp 复制代码
void test_hmset_hmget_hkeys_hvals(Redis&redis){
redis.flushall();

    redis.hmset("key1", {std::make_pair("1", "2"), std::make_pair("2", "3")}); // 也可以pair类型迭代器
    vector<std::string> vp;
    auto bt=std::back_inserter(vp);
    redis.hmget("key1",{"1","2"},bt);
    cout<<" hmget : "<<endl;
    print(vp);
    vp.clear();
    bt=std::back_inserter(vp);
    redis.hkeys("key1",bt);
    cout<<" hmkeys : "<<endl;

    print(vp);
    vp.clear();
    bt=std::back_inserter(vp);
    redis.hvals("key1",bt);
    cout<<" hmget : "<<endl;

    print(vp);
}

测试总代码

点我速看

五.C++之Redis客户端 Zset基础操作

1.Zset的zadd zrange zcard zrem选项

测试效果:

测试代码:

cpp 复制代码
void test_zadd_zrange_zcard_zrem(Redis &redis)
{

    redis.flushall();
    redis.zadd("key1", {std::make_pair("zhangsan", 99), std::make_pair("lisi", 91), std::make_pair("tianqi", 0)});
    // 这里需要带score就传递迭代器的时候传递pair对应的,否则就直接传递String类型
    vector<std::pair<string, double>> vp;
    auto bt = std::back_inserter(vp);
    redis.zrange("key1", 0, -1, bt);
    cout << "zrange:";

    printpair(vp);
    cout << "zcard: " << redis.zcard("key1") << endl;
    redis.zrem("key1", "lisi");
    cout << "zcard: " << redis.zcard("key1") << endl;
}

2.Zset的zrank zscore zinter zunion选项

测试效果:


测试代码:

cpp 复制代码
void test_zrank_zscore_zinter_zunion(Redis &redis)
{

    redis.flushall();
    redis.zadd("key1", {std::make_pair("zhangsan", 99), std::make_pair("lisi", 91), std::make_pair("tianqi", 101)});
    redis.zadd("key2", {std::make_pair("zhangsan", 99), std::make_pair("lisi", 91), std::make_pair("zhaosi", 0)});

  cout<<"rank: "<< redis.zrank("key1","tianqi").value()<<endl;
  cout<<"score: "<< redis.zscore("key1","tianqi").value()<<endl;
  vector<string> v({"key1","key2"});
   redis.zinterstore("des1",v.begin(),v.end());
   redis.zunionstore("des2",v.begin(),v.end());

}

测试总代码

点我速看

六.基于C++Redis客户端简单使用的小结:

  1. 参数传递:当函数参数需传递多个值时,常支持初始化列表或一对迭代器的方式。
  2. 返回值处理:若函数返回值要表示多个数据,一般借助插入迭代器向容器添加元素(如不同类型的迭代器)。
  3. 无效值处理 :在涉及无效值的场景中,常搭配std::optional使用。
  4. 广泛适用性:很多C++代码都采用上述设计方式(实现多模版化+解耦合)。

七.本篇小结

本文详解C++用redis-plus-plus操作Redis的各类命令,涵盖String/List/Set等数据类型,结合optional与迭代器处理参数及返回值,附完整代码。

相关推荐
对牛乱弹琴的秦始皇1 天前
一次 STS 缓存优化引发的 Android 视频上传“分片权限”问题复盘
redis·android-studio
我爱学习好爱好爱1 天前
Prometheus监控栈 监控Springboot2+Vue3+redis项目
数据库·redis·prometheus
czlczl200209251 天前
SpringBoot自定义Redis
spring boot·redis·后端
Go高并发架构_王工1 天前
Redis命令执行原理与源码分析:深入理解内部机制
数据库·redis·后端
Wang15301 天前
c++与Java谁的性能更胜一筹
java·c++
Tipriest_1 天前
C++ 中 std::move 的使用方法与注意事项
c++·move
yuuki2332331 天前
【C++】vector底层实现全解析
c++·后端·算法
小尧嵌入式1 天前
C++选择排序插入排序希尔排序快排归并排及大小根堆实现优先级队列
数据结构·c++·windows·算法·排序算法
Dream it possible!1 天前
LeetCode 面试经典 150_分治_合并 K 个升序链表(108_23_C++_困难)
c++·leetcode·链表·面试·分治
天赐学c语言1 天前
12.29 - 字符串相加 && vector和map的区别
数据结构·c++·算法·leecode