GORM にてテーブルの構造の中に NULL が含まれるカラムがある時はポインタを使う。
簡単に説明するとアスタリスク (*) を使う。
サンプルコード
- DB への接続は Golang + GORM + MySQL でデータをやりとりする を参考。
main.go
package main
import (
"fmt"
"time"
"psychedelicnekopunch/go-sample/infrastructure"
)
/*
CREATE TABLE `books` (
`id` int(10) UNSIGNED NOT NULL,
`title` varchar(255) NOT NULL,
`description` varchar(255) DEFAULT NULL,
`publish_at` int(10) UNSIGNED DEFAULT NULL
);
*/
type Books struct {
ID int `json:"id"`
Title string `json:"title"`
Description *string `json:"description"` // NULL
PublishAt *int64 `json:"publishAt"` // NULL
}
func main() {
d := infrastructure.NewDB()
db := d.Connect()
/**
* Create: 作成
*/
// Description や PublishAt を定義しなかったら、
// 初期値は NULL になる。
// NULL ではないカラムの初期値については、
// string だと空文字、 int だと 0 のようになる。
book := Books{
Title: "Scar Tissue",
}
if !db.NewRecord(&book) {
panic("could not create new record")
}
if err := db.Create(&book).Error; err != nil {
panic(err.Error())
}
/**
* Query: 参照
*/
foundBooks := []Books{}
// SELECT * FROM books;
db.Find(&foundBooks)
if len(foundBooks) == 0 {
fmt.Printf("not found books")
}
fmt.Println(foundBooks)
/**
* Save: 更新
*/
description := "This book is the autobiography of Red Hot Chili Peppers vocalist Anthony Kiedis."
publishAt := time.Now().Unix()
foundBook := Books{}
db.First(&foundBook, book.ID)
// 取得できなかったら ID が初期値の 0 になっている。
if foundBook.ID == 0 {
panic("book not found")
}
// description と publish_at を更新する
foundBook.Description = &description// &"description" のようにはできない。
foundBook.PublishAt = &publishAt// &time.Now().Unix() のようにはできない。
if err := db.Save(&foundBook).Error; err != nil {
panic(err.Error())
}
fmt.Println(foundBook)
// NULL チェックせずにデータを参照しようとして中身が NULL だったら落ちる。
if foundBook.Description != nil {
fmt.Printf("%s\n", *foundBook.Description)
}
if foundBook.PublishAt != nil {
fmt.Print(*foundBook.PublishAt)
}
}
実行
$ go run main.go
[{1 Scar Tissue <nil> <nil>}]
{1 Scar Tissue 0xc000011230 0xc000014560}
This book is the autobiography of Red Hot Chili Peppers vocalist Anthony Kiedis.
1570900000