脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - 在golang xorm中使用postgresql的json,array类型的操作

在golang xorm中使用postgresql的json,array类型的操作

2021-05-28 00:59WwJoyous Golang

这篇文章主要介绍了在golang xorm中使用postgresql的json,array类型的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

xorm支持各种关系数据库,最近使用postgresql时,总是踩到一些坑,在此记录下解决方式。

在使用postgresql的array类型时,查询有点问题,xorm的官方文档给出重写的方式,但是不是很清晰:

官方文档链接:http://xorm.io/docs

在golang xorm中使用postgresql的json,array类型的操作

也就是说碰到基础库不支持的类型,需要我们去重写ToDB、FromDB方法,废话不多说直接上代码:

比如int8[]类型,自定一个Int64Array

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
type Int64Array []int64
 
func (s *Int64Array) FromDB(bts []byte) error {
    if len(bts) == 0 {
        return nil
    }
 
    str := string(bts)
    if strings.HasPrefix(str, "{") {
        str = "[" + str[1:len(str)]
    }
 
    if strings.HasSuffix(str, "}") {
        str = str[0: len(str)-1] + "]"
    }
 
    var ia = &[]int64{}
 
    err := json.Unmarshal([]byte(str), ia)
    if err != nil {
        return err
    }
 
    *s = Int64Array(*ia)
    return nil
}
 
func (s *Int64Array) ToDB() ([]byte, error) {
    return serializeBigIntArray(*s, "{", "}"), nil
}
 
func (arr Int64Array) MarshalJSON() ([]byte, error) {
    return serializeBigIntArrayAsString(arr, "[", "]"), nil
}
 
func (arr *Int64Array) UnmarshalJSON(b []byte) error {
    var strarr []string
    var intarr []int64
 
    err := json.Unmarshal(b, &strarr)
    if err != nil {
        return err
    }
 
    for _, s := range strarr {
        i, err := strconv.ParseInt(s, 10, 64)
        if err != nil {
            return err
        }
 
        intarr = append(intarr, i)
    }
 
    *arr = intarr
    return nil
}
 
func serializeBigIntArray(s []int64, prefix string, suffix string) []byte {
    var buffer bytes.Buffer
 
    buffer.WriteString(prefix)
 
    for idx, val := range s {
        if idx > 0 {
            buffer.WriteString(",")
        }
        buffer.WriteString(strconv.FormatInt(val, 10))
    }
 
    buffer.WriteString(suffix)
 
    return buffer.Bytes()
}
 
func serializeBigIntArrayAsString(s []int64, prefix string, suffix string) []byte {
    var buffer bytes.Buffer
 
    buffer.WriteString(prefix)
 
    for idx, val := range s {
        if idx > 0 {
            buffer.WriteString(",")
        }
        buffer.WriteString("\"")
        buffer.WriteString(strconv.FormatInt(val, 10))
        buffer.WriteString("\"")
    }
    buffer.WriteString(suffix)
    return buffer.Bytes()
}

json类型:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type Cover struct {
 Id   int64  `json:"id,omitempty"`
 Fid  string `json:"fid,omitempty"`
 Type int8   `json:"type,omitempty"`
 Url  string `json:"url,omitempty"`
}
 
func (c *Cover) FromDB(bytes []byte) error {
 return json.Unmarshal(bytes, c)
}
 
func (c *Cover) ToDB() (bytes []byte, err error) {
 bytes, err = json.Marshal(c)
 return
}

具体使用:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Course struct {
    Id            int64             `json:"id,string" form:"id"`
    Name          string            `json:"name" form:"name"`
    Brief         string            `json:"brief" form:"brief"`
    Description   string            `json:"description" form:"description"`
    Cover         common.Cover      `xorm:"Text" json:"cover" form:"cover"`
    Categories    common.Int64Array `xorm:"Text" json:"categories" form:"categories[]"`
    Tags          common.Int64Array `json:"tags" form:"tags[]"`
    Difficulty    float64           `json:"difficulty" form:"difficulty"`
    Price         float64           `json:"price" form:"price"`
    Markets       common.Int64Array `json:"markets" form:"markets[]"`
    StudentAmount int64             `json:"studentAmount" form:"studentAmount"`
    SubjectAmount int64             `json:"subjectAmount" form:"subjectAmount"`
    Crt           time.Time         `json:"crt"`
    Lut           time.Time         `json:"lut"`
    Status        int16             `json:"status" form:"status"`
    common.Page                     `xorm:"-"`
}

补充:golang gin xorm注意事项

1. 无论是golang还是xorm中,在填写j'son字段时,注意空格,比如 `json:"abcd "` `json:"abcd"`是不一样的,不仔细对比会出错

2.当结合gin框中的

?
1
c.JSON(http.StatusOK,gin.H{})操作

并且使用xorm中的join,find操作时(https://www.kancloud.cn/xormplus/xorm/167102)要注意如下现象,

假如定义两个结构体对应两个表

在golang xorm中使用postgresql的json,array类型的操作

然后使用联合查询,先把两个结构体结合成一个结构体,假如如下,在UserGroup中使用User和Group匿名结构体,

在golang xorm中使用postgresql的json,array类型的操作

那么当我们使用gin的c.JSON(http.StatusOK,gin.H{"data":UserGroup})返回数据时会导致Group和User中同名字段显示不了,这应该是gin和xorm的不是很兼容造成的(没有深究),

要解决这个问题,最好让UserGroup中的User和Group不要以匿名结构体的形式存在

可以改成

?
1
2
3
4
type UserGroup struct {
    MyUser  User `xorm:"extends" json:"你要json中返回的名字"`
    MyGroup Group `xorm:"extends" json:"你要json中返回的名字"`
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。如有错误或未考虑完全的地方,望不吝赐教。

原文链接:https://blog.csdn.net/WwJoyous/article/details/80430613

延伸 · 阅读

精彩推荐
  • Golanggolang 通过ssh代理连接mysql的操作

    golang 通过ssh代理连接mysql的操作

    这篇文章主要介绍了golang 通过ssh代理连接mysql的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    a165861639710342021-03-08
  • GolangGolang通脉之数据类型详情

    Golang通脉之数据类型详情

    这篇文章主要介绍了Golang通脉之数据类型,在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等,Go语言中标识符允许由...

    4272021-11-24
  • Golanggolang的httpserver优雅重启方法详解

    golang的httpserver优雅重启方法详解

    这篇文章主要给大家介绍了关于golang的httpserver优雅重启的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    helight2992020-05-14
  • Golanggolang json.Marshal 特殊html字符被转义的解决方法

    golang json.Marshal 特殊html字符被转义的解决方法

    今天小编就为大家分享一篇golang json.Marshal 特殊html字符被转义的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    李浩的life12792020-05-27
  • GolangGolang中Bit数组的实现方式

    Golang中Bit数组的实现方式

    这篇文章主要介绍了Golang中Bit数组的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    天易独尊11682021-06-09
  • Golanggolang如何使用struct的tag属性的详细介绍

    golang如何使用struct的tag属性的详细介绍

    这篇文章主要介绍了golang如何使用struct的tag属性的详细介绍,从例子说起,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看...

    Go语言中文网11352020-05-21
  • Golanggo语言制作端口扫描器

    go语言制作端口扫描器

    本文给大家分享的是使用go语言编写的TCP端口扫描器,可以选择IP范围,扫描的端口,以及多线程,有需要的小伙伴可以参考下。 ...

    脚本之家3642020-04-25
  • Golanggo日志系统logrus显示文件和行号的操作

    go日志系统logrus显示文件和行号的操作

    这篇文章主要介绍了go日志系统logrus显示文件和行号的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    SmallQinYan12302021-02-02