开发者

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

开发者 https://www.devze.com 2023-01-17 10:58 出处:网络 作者: Go~Go~Go~
目录GORM存取数组类型数据一、GORM的自定义类型1. Scanner/Valuer接口2. 数组变量3. 测试二、实际生产​总结GORM存取数组类型数据
目录
  • GORM存取数组类型数据
  • 一、GORM的自定义类型
    • 1. Scanner/Valuer接口
    • 2. 数组变量
    • 3. 测试
  • 二、实际生产
    • ​总结

      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:lon编程gtext"`  // 自定义的数组类型,在数据库中存为长文本类型
      }

      ​ (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 secandroid)
      

      二、实际生产

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

      (1) 实现自定义类型

      type User struct {
       python  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(ciCMgarGLard)
      }
      

      ​ (2) 数据表模型

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

      ​总结

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

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消