はじめに
GolangのORM SQLBoilerを使ってみる - セットアップ編 でセットアップ完了したので、実際にSQLBoilerを使って実装してみたいと思います。
初期化
まずは初期化を行います。
初期化ではコネクションプールを作ったり、SQLBoiler自体の設定をしたりします。
今回は発行されたSQLを見てみたいので、debugモードにします。
なお、簡単化のため、エラーが出たら全てpanicを起こしています。(良い子は真似しないように)
以下のコードで初期化出来ます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
func initDB() {
dns := "user=postgres dbname=sampledb host=localhost sslmode=disable connect_timeout=10"
con, err := sql.Open("postgres", dns)
if err != nil {
panic(err)
}
// connection pool settings
con.SetMaxIdleConns(10)
con.SetMaxOpenConns(10)
con.SetConnMaxLifetime(300 * time.Second)
// global connection setting
boil.SetDB(con)
boil.DebugMode = true
}
|
insert
まずはinsertをしてみます。insertは非常に簡単に出来ます。
insertしたいテーブルのStructインスタンスを作って、Insertの関数を呼ぶだけです。
1
2
3
4
5
6
|
func insert() {
user := db.User{Email: null.StringFrom("test@example.com"), PasswordDigest: null.StringFrom("digested-password")}
fmt.Printf("before user = %+v\n", user)
user.InsertGP(context.Background(), boil.Infer())
fmt.Printf("after user = %+v\n", user)
}
|
ここで出てくる null.String
はnot null制約がついていないカラムについてnullで覆うことでnull safeな状態になっています。
https://github.com/volatiletech/null
これを実行すると、以下のようなログが出力されます。
1
2
3
4
5
|
$ go run main.go
before user = {ID:0 Email:{String:test@example.com Valid:true} PasswordDigest:{String:digested-password Valid:true} CreatedAt:0001-01-01 00:00:00 +0000 UTC UpdatedAt:0001-01-01 00:00:00 +0000 UTC R:<nil> L:{}}
INSERT INTO "users" ("email","password_digest","created_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id"
[{test@example.com true} {digested-password true} 2019-02-14 14:43:41.253731 +0000 UTC 2019-02-14 14:43:41.253731 +0000 UTC]
after user = {ID:3 Email:{String:test@example.com Valid:true} PasswordDigest:{String:digested-password Valid:true} CreatedAt:2019-02-14 14:43:41.253731 +0000 UTC UpdatedAt:2019-02-14 14:43:41.253731 +0000 UTC R:<nil> L:{}}
|
デフォルトで created_at
と updated_at
に現在時刻を入れてくれます。
もちろん、updateの時は updated_at
だけが更新されます。
update
次にupdateしてみます。
updateも簡単で、entity structのupdateを呼ぶのみです。
1
2
3
4
5
|
func update() {
user := db.User{ID: 1}
user.Email = null.StringFrom("update@example.com")
user.UpdateGP(context.Background(), boil.Infer())
}
|
実行してみるとupdateが発行されているログが確認できます。
1
2
3
|
$ go run main.go
UPDATE "users" SET "email"=$1,"password_digest"=$2,"updated_at"=$3 WHERE "id"=$4
[{update@example.com true} { false} 2019-02-21 14:13:19.8155 +0000 UTC 1]
|
delete
続いてdeleteしてみます。
deleteもupdateのようにentity structのdeleteを呼びます。
1
2
3
4
|
func delete() {
user := db.User{ID: 1}
user.DeleteGP(context.Background())
}
|
実行するとdeleteが発行されています。
1
2
3
|
$ go run main.go
DELETE FROM "users" WHERE "id"=$1
1
|
トランザクション処理
トランザクション処理も簡単にできます。
以下がサンプルコードです。(簡単のためにエラーは無視しています)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
func insertTx() {
ctx := context.Background()
tx, err := boil.BeginTx(ctx, nil)
if err != nil {
panic(err)
}
user := db.User{Email: null.StringFrom("test@example.com"), PasswordDigest: null.StringFrom("digested-password")}
fmt.Printf("before user = %+v\n", user)
err = user.Insert(ctx, tx, boil.Infer())
if err != nil {
tx.Rollback()
panic(err)
}
tx.Commit()
fmt.Printf("after user = %+v\n", user)
}
|
実行すると以下のログが確認できます。
1
2
3
4
5
|
$ go run main.go
before user = {ID:0 Email:{String:test@example.com Valid:true} PasswordDigest:{String:digested-password Valid:true} CreatedAt:0001-01-01 00:00:00 +0000 UTC UpdatedAt:0001-01-01 00:00:00 +0000 UTC R:<nil> L:{}}
INSERT INTO "users" ("email","password_digest","created_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id"
[{test@example.com true} {digested-password true} 2019-03-25 13:52:29.148263 +0000 UTC 2019-03-25 13:52:29.148263 +0000 UTC]
after user = {ID:1 Email:{String:test@example.com Valid:true} PasswordDigest:{String:digested-password Valid:true} CreatedAt:2019-03-25 13:52:29.148263 +0000 UTC UpdatedAt:2019-03-25 13:52:29.148263 +0000 UTC R:<nil> L:{}}
|
まとめ
これでSQLBoilerを使って更新系の処理を行うことができました。
自動生成機能があるので、色々と楽にできる部分が多いですね。
次回は多彩なselectをやってみようと思います。
今回作ったサンプルは以下のリポジトリに入れてあります。
https://github.com/ken-aio/go-sqlboiler-sample