Golang GORM - PostgreSQL JSONB 使用範例

Posted on  Feb 16, 2020  in  Go 程式設計 - 高階  by  Amo Chen  ‐ 1 min read

GORM 是 Golang 生態系中知名的 ORM(Object-Relational Mapping) 函式庫,如果想在 Golang 使用 ORM 相關的功能,不妨試試 GORM!

不過, GORM 文件中比較少篇幅提到 PostgreSQL 的 JSONB 如何使用,本文用以紀錄 GORM 使用 JSONB 的範例,如果沒使用 GORM 經驗的話,建議看過 GORM 文件後再閱讀本篇文章。

本文環境

  • mac0S 10.15
  • go 1.13.5
  • gorm 1.9.11
  • PostgreSQL 12

建議使用 Postgres.appPostico 在 macOS 上建置 PostgreSQL 環境。

JSONB 使用範例

以下是 GORM 的 PostgreSQL JSONB 使用範例:

package main

import (
    "encoding/json"
    "log"
    "fmt"

    "github.com/jinzhu/gorm"
    "github.com/jinzhu/gorm/dialects/postgres"
)

type UserPreference struct {
    gorm.Model
    UserId             string
    Preference         postgres.Jsonb `gorm:"default:'{}'"`
}

type PreferenceMap struct {
    SubscribeEDM bool     `json:"subscribe_edm"`
    PreferTopics []string `json:"prefer_topics"`
}

func (u *UserPreference) GetPreference() PreferenceMap {
    pm := PreferenceMap{}
    v, err := u.Preference.Value()
    if err != nil {
        log.Panicln(err)
    }
    err = json.Unmarshal(v.([]byte), &pm)
    if err != nil {
        log.Panicln(err)
    }
    return pm
}

func (u *UserPreference) SetPreference(v PreferenceMap) {
    b, err := json.Marshal(v)
    if err != nil {
        log.Panicln(err)
    }
	u.Preference = postgres.Jsonb{b}
}

func main() {
    connStr := fmt.Sprintf(
        "host=%s port=%s user=%s dbname=%s password=%s sslmode=disable",
        os.Getenv("POSTGRES_HOST"),
        os.Getenv("POSTGRES_PORT"),
        os.Getenv("POSTGRES_USER"),
        os.Getenv("POSTGRES_DBNAME"),
        os.Getenv("POSTGRES_PASSWORD"),
    )
    db, err := gorm.Open("postgres", connStr)
    if err != nil {
        panic(err)
    }
    db.AutoMigrate(UserPreference{})
    userPref := UserPreference{UserId: "1"}
    userPref.SetPreference(PreferenceMap{SubscribeEDM: true})
    db.Create(&userPref)
    
    userPref = UserPreference{}
    db.First(&userPref)
    fmt.Println(userPref.GetPreference())
}

上述範例主要在第 18 行定義 JSONB 欄位要存的結構之後,再分別實作 GetPreferenceSetPreference 2 個方法。

其中,第 25 行的 v, err := u.Preference.Value() 中的 Value() 能夠讓我們取得 JSONB 欄位中的值,接著才能在第 29 行利用 JSON package 提供的方法轉成我們要的資料結構。

而儲存 JSONB 的重點則是在第 41 行用 postgres.Jsonb 包裝起來的部分,必須用 postgres.Jsonb 才能順利將資料轉成 JSONB 。

以上, Happy Coding!

References

https://godoc.org/github.com/jinzhu/gorm/dialects/postgres?hide=1&import-graph=#Jsonb

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!