使用しているライブラリはgo-sql-driver/mysqlですが、実際はdatabase/sqlパッケージ内のAPIの使い方だったりします。
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "gotest:gotest@/demo")
if err != nil {
fmt.Printf("Failed to connect")
return
}
defer db.Close()
statement, err := db.Prepare("SELECT id,email FROM user")
if err != nil {
fmt.Printf("Failed to prepare : %s", err)
return
}
defer statement.Close()
rows, err := statement.Query()
if err != nil {
fmt.Printf("Failed to execute Query")
return
}
defer rows.Close()
for rows.Next() {
var id string
var email string
rows.Scan(&id, &email)
fmt.Printf("id=%s email=%s\n", id, email)
}
}
上から順に見ていきましょう。
db, err := sql.Open("mysql", "gotest:gotest@/demo")
if err != nil {
fmt.Printf("Failed to connect")
return
}
defer db.Close()
sql.Open()メソッドでDBオブジェクトを作ります。ダメだったらerrに何かセットされます。第2引数の形式は"ユーザー名:パスワード@データベース名"です。メソッドを抜けたら確実にClose()するため、deferを使います。
statement, err := db.Prepare("SELECT id,email FROM user")
if err != nil {
fmt.Printf("Failed to prepare : %s", err)
return
}
defer statement.Close()
いろんな言語で見慣れたPreparedStatementオブジェクトを作ります。今回はパラメータがありませんが、必要な場合はこれまた他の言語と同様に"?"を使います。
rows, err := statement.Query()
if err != nil {
fmt.Printf("Failed to execute Query")
return
}
defer rows.Close()
実行します。?パラメータがある場合はQuery()メソッドの引数として渡します。成功するとRowsオブジェクトが返ってきます。
for rows.Next() {
var id string
var email string
rows.Scan(&id, &email)
fmt.Printf("id=%s email=%s\n", id, email)
}
レコードを読む方法です。このライブラリの場合、結果はmapinterface{}で取得できる訳ではなく、SELECTで指定した順でScan()メソッドの引数にポインタを渡すことで取得できます。なので、SELECT * で取得すると、テーブル定義がずれたときひどい目に合います。。。