[Go言語] database/sqlパッケージを使ってみた

October 2, 2013

この記事はQiitaの記事をエクスポートしたものです。内容が古くなっている可能性があります。

ドライバを入れる

MySQLのドライバをいれてみる。

go get "github.com/go-sql-driver/mysql"

使うときは、init関数を呼び出せばよいみたいなので、_でインポートする。

import _ "github.com/go-sql-driver/mysql"

データベースを開く

ドライバの名前を指定して、データベースに接続する。

cnn := sql.Open("mysql", "user:password@tcp(host:port)/dbname")

1レコードをSELECTしてみる

QueryRowメソッドを使えば、1レコード分を取得できる。 Go言語得意のポイントを渡して、出力引数で受け取る。

id := 100
var name string

if err := cnn.QueryRow("SELECT name FROM person WHERE id = ?LIMIT 1", id).Scan(&name); err != nil {
	log.Fatal(err)
}

fmt.Println(id, name)

複数レコードをSELECTしてみる

Queryメソッドを使えば、複数のレコードを取得できる。

rows, err := cnn.Query("SELECT id, name FROM person")
if err != nil {
	log.Fatal(err)
}
defer rows.Close()

for rows.Next() {
	var id int
	var name string	
	if err := rows.Scan(&id, &name); err != nil {
		log.Fatal(err)
	}
	fmt.Println(id, name)
}

if err := rows.Err(); err != nil {
	log.Fatal(err)
}

UPDATEしてみる

レコードを取得する必要のない、クエリはExecメソッドを使う。

result, err := cnn.Exec("UPDATE person SET name = ? WHERE id = ?", "Hogera", 100)
if err != nil {
	log.Fatal(err)
}

Resultインタフェースを使うと、最後に挿入したレコードのキーや影響の合ったレコード数を取得できる。

type Result interface {
        LastInsertId() (int64, error)
        RowsAffected() (int64, error)
}

トランザクションを使ってみる

トランザクションの開始とコミット

Beginメソッドを呼び出すと、Tx型のポインタとエラー値が返ってくる。 Tx型はDB型と似たようなメソッドを持っているため、QueryQueryRowExecなどが使える。

tx, err := cnn.Begin()
if err != nil {
	log.Fatal(err)
}

Commitメソッドを使えばコミットできる。

tx.Commit()

ロールバック

Rollbackメソッドでロールバックできる。 以下の例は、パニックが起きたら、ロールバックする例である。

func hoge(tx *sql.Tx) {
	defer func() {
		// panicがおきたらロールバック
		if err := recover(); err != nil {
			tx.Rollback()
		}
	}()
	// …
	tx.Exec(…)
}

感想

ドキュメントを見ると、コネクションプールとかよしなにやってくれるらしい。 最初は以下のようにやってたけど、不要のようだ。

var cnnPool chan *sql.DB

func main() {
	cnnPool = make(chan *sql.DB, 10)
	for i := 0; i < cap(cnnPool); i++ {
		cnnPool <- sql.Open("mysql", "user:password@tpc(host:port)/dbname")
	}
}

func getFromDB() { 
	cnn := <-cnnPool
	defer func() {
		cnnPool <- cnn
	}()
	// cnnを使った処理
}

まだまだ、使い始めたばっかなので、基本的な使い方だけまとめた。