GORM について
GORM は Go 言語用の ORM です。
検証用 DBテーブルの用意
Docker Compose 設定
compose.yaml
services:
postgres:
image: postgres:17
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
postgres_data:
以下のコマンドでテーブルを作成します。
CREATE TABLE tasks(
id uuid PRIMARY KEY,
title varchar(100) NOT NULL
);
作成されたテーブル
postgres=# \d tasks;
Table "public.tasks"
Column | Type | Collation | Nullable | Default
--------+------------------------+-----------+----------+---------
id | uuid | | not null |
title | character varying(100) | | not null |
Indexes:
"tasks_pkey" PRIMARY KEY, btree (id)
インストール
以下のコマンドを使用してモジュールをインストールします。
GORM のドキュメント に従ってインストールします。
go get -u gorm.io/gorm
go get -u gorm.io/driver/postgres
GORM を使用した CRUD 操作
GORM を使用したシンプルな CRUD 操作を試してみます。
また、UUID の生成に以下を使用します。
Create
main.go
package main
import (
"fmt"
"os"
"github.com/google/uuid"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Task struct {
ID uuid.UUID
Title string
}
func main() {
dsn := fmt.Sprintf("host=localhost user=postgres password=%s port=5432 sslmode=disable TimeZone=Asia/Tokyo", os.Getenv("POSTGRES_PASSWORD"))
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
task := &Task{
ID: uuid.New(),
Title: "Test title",
}
db.Debug().Create(task)
fmt.Printf("%+v", task)
}
go run ./main.go
2024/11/25 23:46:06 /Users/hirotowatanabe/workspace/tmp_20241125_gorm_for_blog/main.go:29
[8.060ms] [rows:1] INSERT INTO "tasks" ("id","title") VALUES ('f5be0266-86d9-48d8-8cdc-93868d767bb0','Test title')
&{ID:f5be0266-86d9-48d8-8cdc-93868d767bb0 Title:Test title}
postgres=# SELECT * FROM tasks WHERE id = 'f5be0266-86d9-48d8-8cdc-93868d767bb0';
id | title
--------------------------------------+------------
f5be0266-86d9-48d8-8cdc-93868d767bb0 | Test title
(1 row)
Read
main.go
package main
import (
"fmt"
"os"
"github.com/google/uuid"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Task struct {
ID uuid.UUID
Title string
}
func main() {
dsn := fmt.Sprintf("host=localhost user=postgres password=%s port=5432 sslmode=disable TimeZone=Asia/Tokyo", os.Getenv("POSTGRES_PASSWORD"))
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
var task Task
db.First(&task, "id = ?", "586ccac4-6346-4ee2-a058-48633161c30e")
fmt.Printf("%+v", task)
}
go run ./main.go
{ID:586ccac4-6346-4ee2-a058-48633161c30e Title:Test title}
Update
main.go
package main
import (
"fmt"
"os"
"github.com/google/uuid"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Task struct {
ID uuid.UUID
Title string
}
func main() {
dsn := fmt.Sprintf("host=localhost user=postgres password=%s port=5432 sslmode=disable TimeZone=Asia/Tokyo", os.Getenv("POSTGRES_PASSWORD"))
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
var task Task
db.First(&task, "id = ?", "f5be0266-86d9-48d8-8cdc-93868d767bb0")
fmt.Printf("SELECTED: %+v", task)
task.Title = "Updated test title"
db.Debug().Save(task)
fmt.Printf("UPDATED: %+v", task)
}
go run ./main.go
SELECTED: {ID:f5be0266-86d9-48d8-8cdc-93868d767bb0 Title:Test title}
2024/11/25 23:52:04 /Users/hirotowatanabe/workspace/tmp_20241125_gorm_for_blog/main.go:31
[4.305ms] [rows:1] UPDATE "tasks" SET "id"='f5be0266-86d9-48d8-8cdc-93868d767bb0',"title"='Updated test title' WHERE "id" = 'f5be0266-86d9-48d8-8cdc-93868d767bb0'
UPDATED: {ID:f5be0266-86d9-48d8-8cdc-93868d767bb0 Title:Updated test title}
postgres=# SELECT * FROM tasks WHERE id = 'f5be0266-86d9-48d8-8cdc-93868d767bb0';
id | title
--------------------------------------+--------------------
f5be0266-86d9-48d8-8cdc-93868d767bb0 | Updated test title
(1 row)
Delete
main.go
package main
import (
"fmt"
"os"
"github.com/google/uuid"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Task struct {
ID uuid.UUID
Title string
}
func main() {
dsn := fmt.Sprintf("host=localhost user=postgres password=%s port=5432 sslmode=disable TimeZone=Asia/Tokyo", os.Getenv("POSTGRES_PASSWORD"))
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
var task Task
db.First(&task, "id = ?", "f5be0266-86d9-48d8-8cdc-93868d767bb0")
fmt.Printf("SELECTED: %+v", task)
db.Debug().Delete(task)
}
go run ./main.go
SELECTED: {ID:f5be0266-86d9-48d8-8cdc-93868d767bb0 Title:Updated test title}
2024/11/25 23:55:21 /Users/hirotowatanabe/workspace/tmp_20241125_gorm_for_blog/main.go:29
[4.327ms] [rows:1] DELETE FROM "tasks" WHERE "tasks"."id" = 'f5be0266-86d9-48d8-8cdc-93868d767bb0'
postgres=# SELECT * FROM tasks WHERE id = 'f5be0266-86d9-48d8-8cdc-93868d767bb0';
id | title
----+-------
(0 rows)