首页 文章

如何使用GORM存储嵌入式结构?

提问于
浏览
7

如果我有这样的类型,如何使用GORM存储嵌入式结构

type A struct {
    point GeoPoint
}

type GeoPoint struct {
    Lat float64
    Lon float64
}

GORM尝试将其添加到新表中,但我想将其添加为另一个字段 .

如何才能做到这一点?

3 回答

  • 0

    我不熟悉Gorm,但是使用 sqlx ,您需要实现sql.Scanner和sql.Valuer接口,以允许将数据转换为postgres point 类型 . 下面的代码不会检查错误,因此需要进行一些调整 .

    https://play.golang.org/p/2-Y-wSeAWnj

    package main
    
    import (
        "database/sql/driver"
        "fmt"
        "strconv"
        "strings"
    )
    
    type GeoPoint struct {
        Lat float64
        Lon float64
    }
    
    func (gp GeoPoint) Value() (driver.Value, error) {
        return fmt.Sprintf("(%d,%d)", gp.Lat, gp.Lon), nil
    }
    
    func (gp GeoPoint) Scan(src interface{}) error {
        raw := src.(string)
        coords := raw[1 : len(raw)-1]
        vals := strings.Split(coords, ",")
        gp.Lat, _ = strconv.ParseFloat(vals[0], 64)
        gp.Lon, _ = strconv.ParseFloat(vals[1], 64)
        return nil
    }
    
    func main() {
        gp := GeoPoint{Lat: 112, Lon: 53}
        d, _ := gp.Value()
        fmt.Printf("%+v\n", d)
    
        gp.Scan("(53, -110)")
        fmt.Printf("%+v\n", gp)
    }
    
  • 0

    首先,使用gorm你永远不会把字段放到lowwer案例中 .

    如果确保将GeoPoint链接为Aid,则可以使用ForeingKey标记,例如,MAKE SURE Id是表A的主键 .

    type A struct {
        Id int `gorm:"column:"id""`
        Point GeoPoint `gorm:"column:geo_point;ForeignKey:OrderId"`
    }
    
    type GeoPoint struct {
        Aid int
        Lat float64
        Lon float64
    }
    
    func main(){
        ...
        ...
        var as []A
        if e:=db.Model(&A{}).Find(&as).Error;e!=nil{
            handle(e)
        }
        fmt.Println(as)
    }
    

    如果没有通过主键链接 . 你可以使用像中间件

    type A struct {
        Id int `gorm:"column:"id""`
        Point GeoPoint `gorm:"column:geo_point"`
    }
    
    func (a *A) AfterFind()error{
       return db.Model(&GeoPoint{}).First(&(a.Point)).Error
    }
    
    type GeoPoint struct {
        Aid int
        Lat float64
        Lon float64
    }
    
    func main(){
        ...
        ...
        var as []A
        if e:=db.Model(&A{}).Find(&as).Error;e!=nil{
            handle(e)
        }
        fmt.Println(as)
    }
    
  • 0

    你可以试试:

    type A struct {
        point GeoPoint `gorm:"embedded"`
    }
    

相关问题