Go Conference(GoCon)で「database/sql入門」というタイトルで発表してきた。 この記事は資料中のリンクや、口頭で説明した内容の補足資料となる。
発表資料
サンプルコードは以下になる。
database/sql入門 | 2019 Spring Sessions
データベースサーバについて
DockerHubを使えば使い捨てのRDSをすぐ起動することができる。 DockerHubを見れば公式イメージがある。
- mysql | Docker Hub
マイグレーションツールについて
sql-migrate
を推した。
リポジトリパターンについて
設計パターンとして、DBをあつかうときに大抵は選択するであろうリポジトリパターンを紹介した。
pospomeさんがBOOTHで販売しているpospomeのサーバサイドアーキテクチャ
にGoで書かれた「第4章 詳解リポジトリパターン」という章があるのでそちらを読むと良い(その前の章のアーキテクチャ設計に関する部分も大変参考になる)。
ORMについて
ORMについてはizumin
さんらが比較記事を書かれているのでそちらを読んでるとよい。
- Go の ORM / query builder 消耗日記 | blog.izum.in
database/sqlパッケージの使い方について
GoDocをみるのが一番よい。
たとえば、sql.Open
関数は一度だけ呼び出せばよい、など、GoDocを見ると使用上の注意がしっかり書かれている。
The returned DB is safe for concurrent use by multiple goroutines and maintains its own pool of idle connections. Thus, the Open function should be called just once. It is rarely necessary to close a DB.
ざっくりサマリを読みたいときはGo Wikiに記事がある。
GoDocサーバの裏でDBは動いていないので実行してもエラーになってしまうが、Examplesにサンプルコードが大量にあるのでそちらを参考にできる。
// https://golang.org/pkg/database/sql/#example_DB_QueryContext
package main
import (
"context"
"database/sql"
"fmt"
"log"
"strings"
)
var (
ctx context.Context
db *sql.DB
)
func main() {
age := 27
rows, err := db.QueryContext(ctx, "SELECT name FROM users WHERE age=?", age)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
names := make([]string, 0)
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
// Check for a scan error.
// Query rows will be closed with defer.
log.Fatal(err)
}
names = append(names, name)
}
// If the database is being written to ensure to check for Close
// errors that may be returned from the driver. The query may
// encounter an auto-commit error and be forced to rollback changes.
rerr := rows.Close()
if rerr != nil {
log.Fatal(err)
}
// Rows.Err will report the last error encountered by Rows.Scan.
if err := rows.Err(); err != nil {
log.Fatal(err)
}
fmt.Printf("%s are %d years old", strings.Join(names, ", "), age)
}
テストについて
オブジェクトのモックを作るときはgo-mock
などを利用するだろう。
sql.DB
オブジェクトもmockを作ることができて、sql-mock
というライブラリもある。
また、Dockerを使ってコードの中からSQLサーバを立ち上げたいときはtest-mysqld
ライブラリが使える。
コードの中からDockerを立ち上げるdockertest
というライブラリもあるので、Dockerイメージで立ち上げるときはこちらを使う。
もっと深い話は@codehexさんや__timakin__
さんの記事を読むと良い。
CircleCIについて
省略してしまったが、CircleCIの設定方法の基本は以下になる。
- Language Guide: Go
CircleCI上でMySQLなどのDBサーバを使う設定をしたいときは、以下のページを参考にconfig.yml
を書いていけば良い。
- Database Configuration Examples
最後に
SpeakerDeckにアップしている資料は少し古いので直したいのだが、オリジナルデータのKeyNoteファイルが壊れてしまって開けなくなってしまった。 KeyNoteを閉じる→開くとファイルが壊れている、ということが度々あるのだが使い方が悪いのだろうか…
GoConで発表する(くらいのスキルを身につける)のは長年の夢だったので今回登壇できてとても嬉しい。 ただ、今回の内容はビギナー向けの発表だった。 初心者向けがよくないわけではないが、他の発表者のみなさんのような中級者・上級者向けの発表もできる、あるいは議論できるくらいのスキルを身につけていきたい。
Gopherくんもらう(GoCon登壇して貰えるくらいの発表をできるようになる)のずっと夢だったから嬉しい pic.twitter.com/DSkcicED1J
— Yoichiro Shimizu (@budougumi0617) May 19, 2019
Gopherくんかわいい。
参考
- https://gocon.jp
- database/sql入門 | Speakerdeck
- https://github.com/budougumi0617/go-sql-sample
- mysql | Docker Hub
- https://github.com/rubenv/sql-migrate
- Go の ORM / query builder 消耗日記 | blog.izum.in
- 【10/5 更新】技術書典5にサークルとして参加します。 | pospomeのプログラミング日記
- https://golang.org/pkg/database/sql/
- https://github.com/DATA-DOG/go-sqlmock
- https://github.com/golang/mock
- https://github.com/ory/dockertest/
- https://github.com/lestrrat-go/test-mysqld
- mercari.go #1 で「もう一度テストパターンを整理しよう」というタイトルで登壇しました | アルパカ三銃士
- GoのAPIのテストにおける共通処理 | Medium
- Language Guide: Go
- Database Configuration Examples