Golang Go语言中 gorm 如何存数组

发布于 1周前 作者 songsunli 来自 Go语言

Golang Go语言中 gorm 如何存数组

各位大佬,请问如何使用 gorm 保存切片,下面是我出错的代码

结构体

type Node struct {
	ID     int    `json:"id"`
	Name   string `json:"name"`
	Author string `json:"author"`
	IP   []string `json:"ip"`
}

Gorm 保存

ips:=[]string{"1.1.1.1","2.2.2.2","3.3.3.3"}
body := Node{Name: "testName", Author: "testAuthor", Node: ips}
if err := DB.Create(&body).Error; err != nil {
	return false
}

得到报错

unsupported data type: &[]

我想存入数据库的数据形式是:

"1.1.1.1","2.2.2.2","3.3.3.3"

前端发来的数据,只能是一个数组包含着 ip,还不能改。。。 这种情况下,问下大佬们我该咋整 T_T


更多关于Golang Go语言中 gorm 如何存数组的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

我之前的做法是转了字符串存起来,然后用的时候再转回数组

更多关于Golang Go语言中 gorm 如何存数组的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


``` golang
type Node struct {

IPList ipList json:"ip" binding:”gt=0,dive,ipv4“
}

type ipList []string

// gorm 自定义结构需要实现 Value Scan 两个方法
// Value 实现方法
func (p ipList ) Value() (driver.Value, error) {
return json.Marshal§
}

// Scan 实现方法
func (p *ipList ) Scan(data interface{}) error {
return json.Unmarshal(data.([]byte), &p)
}


自定义结构我是这么实现的

谢谢老哥,咱俩想的一样,但是我这情况有点特殊,前端发来的数据结构体必须要保持[]string 的类型才可以收到,又不想大改,就没用这个方法

感谢大佬,无脑复制您的代码,把 node 改成 ipList 类型后,一下就成功了,爽的不要不要的~

sql: Scan error on column index 5, name “node”: invalid character ‘.’ after top-level value;


大佬好,使用这个方法之后,不知道为什么,不能读了,读取数据的时候,报上面这个错误

知道了 哈哈,是表中老数据的问题,打扰大佬了

AfterFind hook

用 postgres.jsonb 类型

要对 ip 做查询做索引时你就知错

应该另外建表,存成多行

不知道你用的是 gorm V1 还是 V2,如果使用的 PostgreSQL 且版本为 V1 的话可以直接定义类型为 pq.StringArray,V2 好像改了 PostgreSQL 的 driver 从 pq 到 pgx,这种写法就不行了

大佬好,请问存成多行是什么意思

是说新建一张表 2 个字段 app ip
比如一个 app 名字叫 test 有 3 个 ip,另一个 app 名字是 test1,有 2 个 ip,那表中内容就是

test 1.1.1.1
test 2.2.2.2
test 3.3.3.3
test1 4.4.4.4
test1 5.5.5.5

然后对 ip 字段做索引,是这样嘛?

在Go语言中,使用GORM(Go Object-Relational Mapping)库时,你可以通过多种方式将数组(或切片)存储到数据库中。以下是几种常见的方法:

  1. JSON字段: 如果数组的内容不是固定类型或者数量变化较大,你可以将数组序列化为JSON字符串并存储在一个VARCHAR或TEXT类型的字段中。

    type User struct {
        ID     uint
        Name   string
        Hobbies []string `gorm:"type:text"` // 使用JSON序列化存储
    }
    
    func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
        u.Hobbies, err = json.Marshal(u.Hobbies)
        return
    }
    
    func (u *User) AfterFind(tx *gorm.DB) (err error) {
        err = json.Unmarshal(u.Hobbies, &u.Hobbies)
        return
    }
    
  2. 关联表: 如果数组内容具有固定的结构且数量较多,可以考虑使用关联表(Many-to-Many或One-to-Many关系)。例如,用户可以拥有多个标签,每个标签可以属于多个用户。

    type User struct {
        ID   uint
        Name string
        Tags []Tag `gorm:"many2many:user_tags;"`
    }
    
    type Tag struct {
        ID   uint
        Name string
    }
    

    这种方法的好处是数据库查询更加灵活,可以单独查询、更新或删除关联数据。

选择哪种方法取决于你的具体需求,如数据规模、查询性能、数据一致性等。

回到顶部