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.app 跟 Postico 在 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 欄位要存的結構之後,再分別實作 GetPreference
與 SetPreference
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