1.hmget 接口
hmget 是一个 Redis C++ 客户端库(redis-plus-plus)中的函数,用于批量获取 Hash 类型数据中的多个字段值。
接口说明
cpp
template <typename Input, typename Output>
inline void Redis::hmget(const StringView &key, Input first, Input last, Output output)
参数解释:
- key: Hash 的键名
- first, last: 输入迭代器范围,指定要获取的字段名列表
- output: 输出迭代器,用于接收返回的值
使用示例
示例 1: 使用 vector 存储字段名和结果
cpp
#include <sw/redis++/redis++.h>
#include <vector>
#include <string>
#include <iostream>
using namespace sw::redis;
int main() {
// 连接 Redis
auto redis = Redis("tcp://127.0.0.1:6379");
// 假设 Redis 中有一个 hash: user:1001
// HSET user:1001 name "张三" age "25" email "zhangsan@example.com"
// 定义要获取的字段名
std::vector<std::string> fields = {"name", "age", "email"};
// 准备接收结果的容器
std::vector<OptionalString> results;
// 调用 hmget
redis.hmget("user:1001", fields.begin(), fields.end(), std::back_inserter(results));
// 处理结果
for (size_t i = 0; i < fields.size(); ++i) {
if (results[i]) {
std::cout << fields[i] << ": " << *results[i] << std::endl;
} else {
std::cout << fields[i] << ": (nil)" << std::endl;
}
}
return 0;
}
示例 2: 使用数组
cpp
// 使用 C 风格数组
const char* fields[] = {"name", "age", "email"};
std::vector<OptionalString> results;
redis.hmget("user:1001",
std::begin(fields),
std::end(fields),
std::back_inserter(results));
示例 3: 直接指定字段列表
cpp
// 使用 initializer_list
std::vector<std::string> fields = {"field1", "field2", "field3"};
std::vector<OptionalString> values;
redis.hmget("myhash",
fields.begin(),
fields.end(),
std::back_inserter(values));
// 访问结果
if (values[0]) {
std::cout << "field1 = " << *values[0] << std::endl;
}
关键点说明
OptionalString: 返回值类型,因为字段可能不存在,所以用 Optional 包装- 如果字段存在:
OptionalString包含实际值 - 如果字段不存在:
OptionalString为空(类似 nullptr)
- 如果字段存在:
OptionalString 不是 C++ 标准库的类型,而是 redis-plus-plus 库自己定义的类型。 在
redis-plus-plus 中,OptionalString 通常定义为:
cpp//Optional 是redis自定义的一个模板类 using OptionalString = Optional<std::string>;
-
迭代器模式:
Input可以是任何输入迭代器(vector、list、数组等的 begin/end)Output通常是插入迭代器(如std::back_inserter)
-
结果顺序: 返回值的顺序与请求字段的顺序一致
-
检查空值 : 使用前一定要检查
OptionalString是否有值
2.hmset 接口
HMSET 是 Redis 中用于批量设置 Hash 字段值的命令。在 redis-plus-plus 库中有多种使用方式。
基本用法示例
好的,我用和之前 hmget 一样的例子来讲解 hmset。
HMSET 使用示例
示例 1: 使用 initializer_list(最常用)
cpp
#include <sw/redis++/redis++.h>
#include <string>
#include <iostream>
using namespace sw::redis;
int main() {
auto redis = Redis("tcp://127.0.0.1:6379");
// 批量设置 user:1001 的多个字段
redis.hmset("user:1001", {
{"name", "张三"},
{"age", "25"},
{"email", "zhangsan@example.com"}
});
std::cout << "数据设置成功!" << std::endl;
return 0;
}
示例 2: 使用 vector of pairs
cpp
#include <sw/redis++/redis++.h>
#include <vector>
#include <string>
using namespace sw::redis;
int main() {
auto redis = Redis("tcp://127.0.0.1:6379");
// 准备要设置的字段和值
std::vector<std::pair<std::string, std::string>> user_data;
user_data.push_back({"name", "李四"});
user_data.push_back({"age", "30"});
user_data.push_back({"email", "lisi@example.com"});
user_data.push_back({"phone", "13800138000"});
// 批量设置
redis.hmset("user:1002", user_data.begin(), user_data.end());
return 0;
}
示例 3: 使用 unordered_map
cpp
#include <sw/redis++/redis++.h>
#include <unordered_map>
#include <string>
using namespace sw::redis;
int main() {
auto redis = Redis("tcp://127.0.0.1:6379");
// 使用 map 存储数据
std::unordered_map<std::string, std::string> user_info;
user_info["name"] = "王五";
user_info["age"] = "28";
user_info["city"] = "上海";
// 批量设置 - 使用迭代器
redis.hmset("user:1003", user_info.begin(), user_info.end());
return 0;
}
示例 4: HMSET + HMGET 完整流程
cpp
#include <sw/redis++/redis++.h>
#include <vector>
#include <string>
#include <iostream>
using namespace sw::redis;
int main() {
auto redis = Redis("tcp://127.0.0.1:6379");
// ========== 第一步:批量设置数据 ==========
redis.hmset("user:1001", {
{"name", "张三"},
{"age", "25"},
{"email", "zhangsan@example.com"},
{"city", "北京"}
});
std::cout << "=== 数据已设置 ===" << std::endl;
// ========== 第二步:批量读取数据 ==========
std::vector<std::string> fields = {"name", "age", "email", "city"};
std::vector<OptionalString> results;
redis.hmget("user:1001",
fields.begin(),
fields.end(),
std::back_inserter(results));
// ========== 第三步:处理结果 ==========
std::cout << "\n=== 读取结果 ===" << std::endl;
for (size_t i = 0; i < fields.size(); ++i) {
std::cout << fields[i] << ": ";
if (results[i]) {
std::cout << *results[i] << std::endl;
} else {
std::cout << "(nil)" << std::endl;
}
}
return 0;
}
输出:
=== 数据已设置 ===
=== 读取结果 ===
name: 张三
age: 25
email: zhangsan@example.com
city: 北京
示例 5: 动态构建数据后设置
cpp
#include <sw/redis++/redis++.h>
#include <map>
#include <string>
#include <iostream>
using namespace sw::redis;
int main() {
auto redis = Redis("tcp://127.0.0.1:6379");
// 动态构建用户数据
std::map<std::string, std::string> user_data;
user_data["name"] = "赵六";
user_data["age"] = "35";
user_data["department"] = "技术部";
user_data["position"] = "工程师";
// 批量设置到 Redis
std::string user_key = "user:1004";
redis.hmset(user_key, user_data.begin(), user_data.end());
std::cout << "用户数据已保存到: " << user_key << std::endl;
// 验证:读取其中一个字段
auto name = redis.hget(user_key, "name");
if (name) {
std::cout << "姓名: " << *name << std::endl;
}
return 0;
}
HMSET 接口形式总结
redis-plus-plus 提供了多种 hmset 重载:
cpp
// 形式1: 使用 initializer_list(最简洁)
redis.hmset("key", {
{"field1", "value1"},
{"field2", "value2"}
});
// 形式2: 使用迭代器范围
redis.hmset("key", first_iterator, last_iterator);
// 其中 iterator 指向 pair<string, string> 或类似结构
// 形式3: 使用 template(支持各种容器)
template <typename Input>
void hmset(const StringView &key, Input first, Input last);
关键点
- 返回值 :
hmset返回void,失败时抛出异常 - 覆盖行为: 如果字段已存在,新值会覆盖旧值
- 原子性: 所有字段要么全部设置成功,要么全部失败
- 异常处理 : 需要捕获
ReplyError、TimeoutError等异常
带异常处理的完整示例
cpp
#include <sw/redis++/redis++.h>
#include <string>
#include <iostream>
using namespace sw::redis;
int main() {
try {
auto redis = Redis("tcp://127.0.0.1:6379");
// 批量设置
redis.hmset("user:1001", {
{"name", "张三"},
{"age", "25"},
{"email", "zhangsan@example.com"}
});
std::cout << "设置成功!" << std::endl;
} catch (const ReplyError &err) {
std::cerr << "Redis 命令错误: " << err.what() << std::endl;
} catch (const TimeoutError &err) {
std::cerr << "Redis 超时: " << err.what() << std::endl;
} catch (const Error &err) {
std::cerr << "Redis 错误: " << err.what() << std::endl;
}
return 0;
}