Go语言中GORM存取数组/自定义类型数据

 更新时间:2023年01月17日 09:28:09   作者:Go~Go~Go~  
在使用gorm时往往默认的数据类型不满足我们的要求,需要使用一些自定义数据类型作为字段类型,下面这篇文章主要给大家介绍了关于Go语言中GORM存取数组/自定义类型数据的相关资料,需要的朋友可以参考下

GORM存取数组类型数据

GORM不支持数组类型变量数据的存取,可以通过GROM的自定义数据类型实现。

一、GORM的自定义类型

1. Scanner/Valuer接口

GORM的自定义的数据类型必须实现Scanner/Valuer接口。

(1) Scanner接口的Scan方法,是从数据库读取数据到Go变量时需要进行的解析处理,与解码的过程类型。

(2) Valuer接口的Value方法,是将Go变量存到数据库时进行编码处理。

2. 数组变量

​ 虽然GORM不支持数组变量,但是可以通过实现Scanner/Valuer接口,在数据库取/存时进行类似解码/编码的处理,使数组变量成为数据库可支持的变量类型。

(1) 实现Sacnner接口

Scan函数,从数据库读取数据后,对其进行处理,然后获得Go类型的变量。

type Strs []string

func (m *Strs) Scan(val interface{}) error {
	s := val.([]uint8)
	ss := strings.Split(string(s), "|")
	*m = ss
	return nil
}

如上自定义Strs类型,底层类型未字符串数组。Scan函数将读取的val值,按照字符串处理,以"|"为分隔符进行切割,获得字符串数组类型,然后使用指针赋值。

(2) 实现Valuer接口

Value函数,将数据存到数据库时,对数据进行处理,获得数据库支持的类型。

func (m Strs) Value() (driver.Value, error) {
	str := strings.Join(m, "|")
	return str, nil
}

如上将Strs存入数据库前,将数组内的字符串用"|"拼接,获得数据库支持的string类型后再存入数据库。

3. 测试

定义如下函数进行测试

(1) 模型变量

type User struct {
	ID   uint `gorm:"primary_key"`
	Name string
	Pics Strs `gorm:"type:longtext"`  // 自定义的数组类型,在数据库中存为长文本类型
}

​ (2) Service函数

func SaveUser(user User) error {
	var err error
	err = db.Save(&user).Error
	return err
}

func GetUser(name string) (User, error) {
	var user User
	err := db.First(&user, "name = ?", name).Error
	return user, err
}

​ (3) testService函数

func TestSaveUser() {
   user := User{
      Name: "Jason",
      Pics: Strs{
         "123124",
         "gtsrbxrzsfcv",
      },
   }
   err := SaveUser(user)
   if err != nil {
      log.Panicln("保存失败!", err)
   } else {
      log.Println("保存成功!")
   }
}

func TestGetUser() {
   user, err := GetUser("Jason")
   if err != nil {
      log.Panicln("获取失败!", err)
   } else {
      log.Println("获取成功!", user)
   }
}

​ (4) 运行结果

2022/07/30 18:18:41 保存成功!
2022/07/30 18:18:41 获取成功! {3 Jason [123124 gtsrbxrzsfcv]}

在数据库存储中体现为:

mysql> select *from users;
+----+-------+---------------------+
| id | name  | pics                |
+----+-------+---------------------+
|  3 | Jason | 123124|gtsrbxrzsfcv |
+----+-------+---------------------+
1 row in set (0.00 sec)

二、实际生产

上面的例子中展示了Scanner/Valuer接口的简单使用,实际生产中将数组类型转换为json字符串进行保存,下面展示一个完整的例子,以一个User拥有一张包含信息的银行卡为例(当然可以通过一对一关联4444实现)。

(1) 实现自定义类型

type User struct {
   ID    uint `gorm:"primary_key"`
   Name  string
   Cards Card `gorm:"json"`
}

type Card struct {  // 指定json的Tag。
   Type     int    `json:"type"`
   Account  string `json:"account"`
   Password string `json:"password"`
}

// Scan 解码json字符串
func (card *Card) Scan(val interface{}) error {
   b, _ := val.([]byte)
   return json.Unmarshal(b, card)
}

// Value 编码json
func (card Card) Value() (value driver.Value, err error) {
	return json.Marshal(card)
}

​ (2) 数据表模型

type User struct {
   ID    uint `gorm:"primary_key"`
   Name  string
   Cards Card `gorm:"json"`  // 指定为json类型
}

​总结

到此这篇关于Go语言中GORM存取数组/自定义类型数据的文章就介绍到这了,更多相关GORM存取数组 自定义类型数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang 基础面试题集锦

    Golang 基础面试题集锦

    这篇文章主要为大家介绍了Golang 基础面试题集锦,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 关于golang中平行赋值浅析

    关于golang中平行赋值浅析

    这篇文章主要给大家介绍了关于golang中平行赋值的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用golang具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-08-08
  • go日志库中的logrus

    go日志库中的logrus

    这篇文章主要介绍了go日志库中的logrus主要包括go日志库logrus的安装和使用,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • Go语言实现的最简单数独解法

    Go语言实现的最简单数独解法

    前面给大家介绍过使用javascript实现的简单的数独解法,小伙伴们都非常喜欢,今天我们再来分享一则go语言实现的简单的数独解法,有需要的小伙伴来参考下。
    2015-03-03
  • Go语言实现Sm2加解密的示例代码

    Go语言实现Sm2加解密的示例代码

    本文主要介绍了Go语言实现Sm2加解密的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Go构建WiFi局域网聊天室示例详解

    Go构建WiFi局域网聊天室示例详解

    这篇文章主要为大家介绍了Go构建WiFi局域网聊天室示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • sublime安装支持go和html的插件

    sublime安装支持go和html的插件

    这篇文章主要介绍了sublime安装支持go和html的插件,需要的朋友可以参考下
    2015-01-01
  • PHP和GO对接ChatGPT实现聊天机器人效果实例

    PHP和GO对接ChatGPT实现聊天机器人效果实例

    这篇文章主要为大家介绍了PHP和GO对接ChatGPT实现聊天机器人效果实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Golang HTTP编程的源码解析详解

    Golang HTTP编程的源码解析详解

    这篇文章主要为大家详细介绍了Golang中的HTTP编程以及源码解析,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的可以了解一下
    2023-02-02
  • Go语言并发之原子操作详解

    Go语言并发之原子操作详解

    代码中的加锁操作因为涉及内核态的上下文切换会比较耗时、代价比较高。针对基本数据类型我们还可以使用原子操作来保证并发安全,本文就来和大家详细聊聊,需要的可以参考下
    2022-12-12

最新评论