0

0

Go 中使用 Redigo 将结构体数组存入并读取 Redis 的完整实践指南

花韻仙語

花韻仙語

发布时间:2025-12-31 13:02:05

|

832人浏览过

|

来源于php中文网

原创

Go 中使用 Redigo 将结构体数组存入并读取 Redis 的完整实践指南

本文详解如何在 go 中借助 redigo 客户端,将 struct 或 struct 切片序列化为 json 存入 redis,并安全反序列化还原,涵盖字段导出、json 编解码、redis 命令选择及常见陷阱。

在 Go 中操作 Redis 存储自定义结构体(如 Resource)时,Redis 本身只支持字符串、字节流等基础类型,因此必须对结构体进行序列化(marshaling)后存储,读取时再反序列化(unmarshaling)。你提供的代码中存在两个关键问题:一是结构体字段 title string 未导出(首字母小写),导致 json.Marshal 无法访问;二是 LPUSH 直接传入结构体对象会触发默认字符串化(非 JSON),无法正确还原。

✅ 正确做法:导出字段 + JSON 序列化 + 合理 Redis 数据结构

首先,修正结构体定义,确保字段可被 encoding/json 访问:

type Resource struct {
    Title string `json:"title"` // 首字母大写(导出),并添加 JSON tag 保持键名一致
}
⚠️ 注意:Go 中只有首字母大写的字段才是导出字段(exported),json 包仅序列化导出字段。原 title string 是私有字段,json.Marshal 将忽略它,结果为空对象 {}。

✅ 示例:保存与读取 struct 切片

以下是一个完整的 Redigo + JSON 实践示例(含错误处理和连接管理):

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/gomodule/redigo/redis"
)

type Resource struct {
    Title string `json:"title"`
}

func main() {
    // 建立 Redis 连接池(生产环境推荐)
    pool := &redis.Pool{
        MaxIdle:     3,
        IdleTimeout: 240 * time.Second,
        Dial: func() (redis.Conn, error) {
            return redis.Dial("tcp", "localhost:6379")
        },
    }
    defer pool.Close()

    conn := pool.Get()
    defer conn.Close()

    // 准备数据
    resources := []Resource{
        {Title: "Getting Started with Go"},
        {Title: "Advanced Redis Patterns"},
        {Title: "Redigo Best Practices"},
    }

    // ✅ 步骤1:序列化为 JSON 字节数组
    data, err := json.Marshal(resources)
    if err != nil {
        log.Fatal("JSON marshal failed:", err)
    }

    // ✅ 步骤2:存入 Redis —— 推荐使用 STRING 类型(语义清晰、读取高效)
    _, err = conn.Do("SET", "resources:list", data)
    if err != nil {
        log.Fatal("Redis SET failed:", err)
    }

    // ✅ 步骤3:从 Redis 读取并反序列化
    reply, err := redis.Bytes(conn.Do("GET", "resources:list"))
    if err != nil {
        log.Fatal("Redis GET failed:", err)
    }

    var loaded []Resource
    err = json.Unmarshal(reply, &loaded)
    if err != nil {
        log.Fatal("JSON unmarshal failed:", err)
    }

    fmt.Printf("Loaded %d resources:\n", len(loaded))
    for i, r := range loaded {
        fmt.Printf("[%d] %s\n", i+1, r.Title)
    }
    // 输出:
    // Loaded 3 resources:
    // [1] Getting Started with Go
    // [2] Advanced Redis Patterns
    // [3] Redigo Best Practices
}

? 关于 LPUSH / LRANGE 的说明(按需选用)

你原计划用 LPUSH 存入单个 struct,这在技术上可行,但需注意:

sematic
sematic

一个开源的机器学习平台

下载
  • 每次 LPUSH 只能推入一个 JSON 字符串(即每个 struct 单独序列化后入队);
  • 读取时需用 LRANGE key 0 -1 获取全部元素,再逐个 json.Unmarshal;
  • 更适合「消息队列」或「需保序追加」场景,而非「整体集合读写」。

若坚持使用列表方式,示例片段如下:

// 存入(每个 struct 独立序列化)
for _, r := range resources {
    b, _ := json.Marshal(r)
    conn.Do("LPUSH", "resources:queue", b)
}

// 读取全部
items, _ := redis.Values(conn.Do("LRANGE", "resources:queue", 0, -1))
var loaded []Resource
for _, item := range items {
    var r Resource
    json.Unmarshal(item.([]byte), &r)
    loaded = append(loaded, r)
}

? 关键注意事项总结

  • 始终导出结构体字段(首字母大写),否则 json 包不可见;
  • 优先使用 SET/GET 存储整个切片的 JSON,语义明确、I/O 更少、性能更优;
  • ✅ 使用 redis.Bytes() 或 redis.String() 辅助函数安全转换返回值,避免类型断言 panic;
  • ⚠️ 避免在 Do() 中直接传入未序列化的 struct——Go 会调用其 String() 方法(若实现)或打印类型名,绝非预期 JSON
  • ? 生产环境务必配置连接池、超时、重试及错误监控;
  • ? 如需查询能力(如按 title 模糊匹配),考虑结合 Redis 模块(RedisJSON、Search)或改用关系型数据库。

通过以上方式,你就能在 Go 中稳定、可维护地将结构化数据持久化至 Redis,并精准还原——既发挥 Redis 的高性能优势,又不失 Go 类型系统的安全性与表达力。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

402

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

528

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

306

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

74

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

resource是什么文件
resource是什么文件

Resource文件是一种特殊类型的文件,它通常用于存储应用程序或操作系统中的各种资源信息。它们在应用程序开发中起着关键作用,并在跨平台开发和国际化方面提供支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

140

2023.12.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

248

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

205

2023.09.04

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 6.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号