登录
首页 >  Golang >  Go问答

使用 GORM golang 持久化自定义集数据类型

来源:Golang技术栈

时间:2023-03-22 17:47:57 329浏览 收藏

学习Golang要努力,但是不要急!今天的这篇文章《使用 GORM golang 持久化自定义集数据类型》将会介绍到golang等等知识点,如果你想深入学习Golang,可以关注我!我会持续更新相关文章的,希望对大家都能有所帮助!

问题内容

Set在 go 中创建了一个自定义数据类型,我用它来定义一对多关系。例如在我的架构中,我有以下结构定义

type Doctor struct {
  firstName string
  lastName string
  capabilities commons.Set
 }

capabilities是一组具有以下值的字符串chat, audio, video,通过此设置,我试图将上述结构坚持到MySQL使用GORM库中,但是当我这样做时,我得到以下错误

panic: invalid sql type Set (interface) for mysql

goroutine 6 [running]:
catalog/vendor/github.com/jinzhu/gorm.(*mysql).DataTypeOf(0xc00027e8a0, 0xc00024d680, 0x8, 0x8)
    /home/kumard/go/src/catalog/vendor/github.com/jinzhu/gorm/dialect_mysql.go:123 +0xce9
catalog/vendor/github.com/jinzhu/gorm.(*Scope).createTable(0xc000169400, 0xc14e60)

我知道我必须实现某些方法才能实现这一点,但我无法确定要在此处实现哪个方法/回调。

ThreadUnsafeSet 定义:

type threadUnsafeSet map[interface{}]struct{}    

type OrderedPair struct {
    First interface{}
    Second interface{}
}    

func newThreadUnsafeSet() threadUnsafeSet {
    return make(threadUnsafeSet)
}    

func (pair *OrderedPair) Equal(other OrderedPair) bool {
    return pair.First == other.First && pair.Second == other.Second
}    

func (set *threadUnsafeSet) Add(i interface{}) bool {
    _, found := (*set)[i]
    if found {
        return false
    }
    (*set)[i] = struct{}{}
    return true
}    

func (set *threadUnsafeSet) Contains(i ...interface{}) bool {
    for _, val := range i {
        if _, ok := (*set)[val]; !ok {
            return false
        }
    }
    return true
}    

func (set *threadUnsafeSet) Cardinality() int {
    return len(*set)
}    

func (set *threadUnsafeSet) Equal(other Set) bool {
    _ = other.(*threadUnsafeSet)
    if set.Cardinality() != other.Cardinality() {
        return false
    }
    for elem := range *set {
        if !other.Contains(elem){
            return false
        }
    }
    return true
}    

func (set *threadUnsafeSet) IsSubSet(other Set) bool {
    _ = other.(*threadUnsafeSet)
    if set.Cardinality() > other.Cardinality() {
        return false
    }
    for elem := range *set {
        if !other.Contains(elem) {
            return false
        }
    }
    return true
}    

func (set *threadUnsafeSet) IsProperSubSet(other Set) bool {
    return set.IsSubSet(other) && !set.Equal(other)
}    

func (set *threadUnsafeSet) IsSuperSet(other Set) bool {
    return other.IsSubSet(set)
}    

func (set *threadUnsafeSet) IsProperSuperSet(other Set) bool {
    return set.IsSuperSet(other) && !set.Equal(other)
}    

func (set *threadUnsafeSet) Union(other Set) Set {
    o := other.(*threadUnsafeSet)
    result := newThreadUnsafeSet()
    for elem := range *set {
        result.Add(elem)
    }
    for elem := range *o {
        result.Add(elem)
    }
    return &result
}    


func (set *threadUnsafeSet) Intersect(other Set) Set {
    o := other.(*threadUnsafeSet)    

    intersection := newThreadUnsafeSet()    

    if set.Cardinality() 

设置接口定义

type Set interface {
    Add(i interface{}) bool    

    Cardinality() int    

    Clear()    

    Clone() Set    

    Contains(i ...interface{}) bool    

    Difference(other Set) Set    

    Equal(other Set) bool    

    Intersect(other Set) Set    

    IsProperSubSet(other Set) bool    

    IsSubSet(other Set) bool    

    IsSuperSet(other Set) bool    

    Each(func(interface{}) bool)    

    Iter() 

正确答案

您需要为自定义类型实现Scanner & Driver Valuer接口,然后数据库驱动程序才能知道如何将数据存储在数据库中以及如何从数据库中获取数据。

func (data *CustomType) Value() (driver.Value, error) {
    ...
}
func (data *CustomType) Scan(value interface{}) error {
    ...
}

示例:假设 UserAccess 是map[interface{}]struct{}类型。

type UserAccess map[interface{}]struct{}

func (data *UserAccess) Value() (driver.Value, error) {
    return data.ConvertJSONToString(), nil
}
func (data *UserAccess) Scan(value interface{}) error {
    *data = data.ConvertStringToJson(valueString)
}

这里用于将自定义数据类型值转换为数据库兼容类型,如 json-string ConvertStringToJsonConvertJSONToString

今天关于《使用 GORM golang 持久化自定义集数据类型》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于golang的内容请关注golang学习网公众号!

声明:本文转载于:Golang技术栈 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表