今回はDB接続周りの話
database接続に関してはGolangは標準パッケージにDB接続用のモジュールが存在する。
http://golang.org/pkg/database/sql/
チュートリアル: http://go-database-sql.org/
日本語資料: https://github.com/astaxie/build-web-application-with-golang/tree/master/ja
で、この辺りで調査したことを報告。
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql",
"root@tcp(127.0.0.1:3306)/hello")
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
超簡単な接続するだけexample
頑張って解説
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
// sql.Open 第一引数にdriverの種類、第二引数に接続アドレスを指定、ここではhelloに接続することを宣言。
db, err := sql.Open("mysql",
"root@tcp(127.0.0.1:3306)/hello")
// errがあればそれを表示
if err != nil {
log.Fatal(err)
}
// deferで関数の終わりにそれをclose
defer db.Close()
}
dbに対して生存チェックをすることも可能。生存チェックはdb.Pingを使う。
func main() {
db, err := sql.Open("mysql",
"root@tcp(127.0.0.1:3306)/hello")
if err != nil {
log.Fatal(err)
}
err = db.Ping()
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
じゃあ次にエントリを取り出してみましょう。
mysqlに対して、事前にデータを作っておいてください。
create database hello
use hello
create table users
(
id INT(10) NOT NULL,
name VARCHAR(32)
);
insert into users (id, name) values (1, "yosuke");
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql",
"root@tcp(127.0.0.1:3306)/hello")
if err != nil {
log.Fatal(err)
}
err = db.Ping()
if err != nil {
log.Fatal(err)
}
// idとnameの変数を宣言
var (
id int
name string
)
// db.Queryを使う。
rows, err := db.Query("select id, name from users where id = ?", 1)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
// rowsのNextでカーソルを操作
for rows.Next() {
// rows.Scanで値をバインドする
err := rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
// 出力!!
log.Println(id, name)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
// db.Prepareで実行
stmt, err := db.Prepare("select id, name from users where id = ?")
if err != nil {
log.Fatal(err)
}
// statementのClose忘れずに。
defer stmt.Close()
// stmt.QueryでQueryを実行
rows, err := stmt.Query(1);
for rows.Next() {
err := rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
log.Println(id, name)
}
defer rows.Close();
こういう時はQueryRowを使いましょう。
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql",
"root@tcp(127.0.0.1:3306)/hello")
if err != nil {
log.Fatal(err)
}
err = db.Ping()
if err != nil {
log.Fatal(err)
}
var (
id int
name string
)
stmt, err := db.Prepare("select id, name from users where id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
// stmt.QueryRowなら一行だけ取得する。
err = stmt.QueryRow(1).Scan(&id, &name)
log.Println(id, name)
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
面倒なRowの扱いがなくなってスッキリしましたね。
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql",
"root@tcp(127.0.0.1:3306)/hello")
defer db.Close()
if err != nil {
log.Fatal(err)
}
err = db.Ping()
if err != nil {
log.Fatal(err)
}
stmt, err := db.Prepare("INSERT INTO users(id, name) VALUES(?, ?)")
if err != nil {
log.Fatal(err)
}
res, err := stmt.Exec(2, "haruyama")
if err != nil {
log.Fatal(err)
}
lastId, err := res.LastInsertId()
if err != nil {
log.Fatal(err)
}
rowCnt, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
log.Printf("ID = %d, affected = %d\n", lastId, rowCnt)
}
とりあえず、INSERTでIDとnameを入れてみる例。 db.Execを使うとINSERT, UPDATE, DELETEが使える。
トランザクション使う例とかもやりたかったけど、
タイムアップ。
後で追記するかも。
Tx.Exec等を使うらしい。