You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Mysql读取数据填充Golang的Struct类型map

Golang从MySQL读取数据填充map类型结构体字段方案

前置说明

MySQL是关系型数据库,无法直接存储Go的map结构,所以你需要先设计两张关联表分别存储流和对应频道的持久化信息。ChannelST中小写开头的非导出字段、通道、切片、map类型的运行时字段不需要存入数据库,查询时手动初始化即可。

表结构设计参考

-- 流信息表
CREATE TABLE `stream` (
  `name` varchar(255) NOT NULL PRIMARY KEY COMMENT '流名称'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 频道信息表,和流表通过stream_name关联
CREATE TABLE `channel` (
  `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `stream_name` varchar(255) NOT NULL COMMENT '关联的流名称',
  `name` varchar(255) NOT NULL COMMENT '频道名称',
  `url` varchar(1024) NOT NULL COMMENT '频道地址',
  `on_demand` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否按需加载',
  `debug` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否开启调试',
  `status` int NOT NULL DEFAULT '0' COMMENT '频道状态',
  `ack` datetime NOT NULL COMMENT '确认时间',
  INDEX `idx_stream_name`(`stream_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

代码实现(以GORM为例)

第一步:定义数据库映射模型

仅包含需要持久化到MySQL的字段即可:

import "time"

// DBStream 对应stream表
type DBStream struct {
    Name string `gorm:"column:name;primaryKey"`
}

// DBChannel 对应channel表
type DBChannel struct {
    StreamName string    `gorm:"column:stream_name"`
    Name       string    `gorm:"column:name"`
    URL        string    `gorm:"column:url"`
    OnDemand   bool      `gorm:"column:on_demand"`
    Debug      bool      `gorm:"column:debug"`
    Status     int       `gorm:"column:status"`
    Ack        time.Time `gorm:"column:ack"`
}

第二步:查询并组装目标结构体

func GetStreamWithChannels(streamName string) (*StreamST, error) {
    // 1. 查询流基础信息
    var dbStream DBStream
    if err := db.Model(&DBStream{}).Where("name = ?", streamName).First(&dbStream).Error; err != nil {
        return nil, err
    }

    // 2. 查询该流关联的所有频道
    var dbChannels []DBChannel
    if err := db.Model(&DBChannel{}).Where("stream_name = ?", streamName).Find(&dbChannels).Error; err != nil {
        return nil, err
    }

    // 3. 组装成StreamST结构,填充Channels map
    stream := &StreamST{
        Name:     dbStream.Name,
        Channels: make(map[string]ChannelST, len(dbChannels)),
    }

    for _, dbChan := range dbChannels {
        chanItem := ChannelST{
            Name:             dbChan.Name,
            URL:              dbChan.URL,
            OnDemand:         dbChan.OnDemand,
            Debug:            dbChan.Debug,
            Status:           dbChan.Status,
            Ack:              dbChan.Ack,
            // 运行时字段手动初始化
            runLock:          false,
            codecs:           make([]av.CodecData, 0),
            sdp:              make([]byte, 0),
            signals:          make(chan int, 1),
            hlsSegmentBuffer: make(map[int]SegmentOld),
            hlsSegmentNumber: 0,
            clients:          make(map[string]ClientST),
        }
        // 以频道名为key存入map
        stream.Channels[chanItem.Name] = chanItem
    }

    return stream, nil
}

注意事项

  • 如果使用原生database/sql库,逻辑完全一致,只是把GORM的查询替换为原生SQL查询、Scan赋值即可。
  • 如果需要批量查询所有流的信息,可先查全量流数据,再查全量频道数据按stream_name分组,逐个组装对应流的Channels map即可。
  • 运行时字段不要存入MySQL,这类动态结构、锁、通道类型本身也不支持序列化存储到关系型数据库。

内容的提问来源于stack exchange,提问作者ziyu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:48:01