こんにちは。scarvizです。
今回はMyMySQLを使ってみます。
基本的には下記の内容と同じです。
https://github.com/ziutek/mymysql
環境は前回同様のUbuntu12.04になります。
前回の記事はこちらです→ http://kobegdg.blogspot.jp/2013/02/go.html
■MyMySQLのインストール
MyMySQLは$GOPATH以下に展開されるため、$GOPATHを設定していない場合は、予め設定しておいてください。
$GOPATHの設定については下記を参考にしてください。
「QtでGo言語をするための環境構築」
http://kobegdg.blogspot.jp/2012/08/qtgo.html
「Go言語で独自パッケージを作成する」
http://kobegdg.blogspot.jp/2013/01/go_19.html
次の3つを実行します。
go get github.com/ziutek/mymysql/thrsafe go get github.com/ziutek/mymysql/autorc go get github.com/ziutek/mymysql/godrv
■MyMySQLのテスト
MyMySQLのテストには「test」というDBに、ユーザ名「testuser」、パスワード「TestPasswd9」でアクセスして操作していきます。
おそらく「test」というDB名は既に存在しているんじゃないかなと思います。
rootユーザでMySQLに接続し、一度「SHOW DATABASES;」でDB一覧を表示して、「test」が存在していることを確認してください。
もし存在している場合は、「USE test;」で「test」に接続、「SHOW TABLES;」でテーブルが定義されていないことを確認してください。
もし、「test」が存在しない場合は、
mysql> CREATE DATABASE test;
を実行してください。
ユーザを作成します。下記コマンドを実行してください。
mysql> GRANT ALL PRIVILEGES ON test.* TO testuser@localhost;
mysql> SET PASSWORD FOR testuser@localhost = PASSWORD("TestPasswd9");
一度、
mysql> EXIT;
で抜けて、下記コマンドを実行してください。
cd $GOPATH/src/github.com/ziutek/mymysql sudo gedit /etc/mysql/my.cnf sudo service mysql restart ./all.bash test
すべて「OK」が表示されていれば、MyMySQLはちゃんとインストールされています。
パッケージも作成されていると思います。
testuserはもう不要なので、削除しても構いません。
MyMySQLのサンプルを試してみたい方はそのままでも良いと思います。
ユーザを削除するには、先にユーザの権限を除いてから削除します。
mysql> REVOKE ALL ON *.* FROM testuser@localhost; mysql> DROP USER testuser@localhost;
■SQL操作 DB接続
GoからテーブルにSELECT,INSERT,UPDATE,DELETEをしてみたいと思います。
前回作成したユーザがDMLしか扱えないユーザとします。
まずは、CREATE権限があるユーザでDBにテーブルを作成しておきます。
mysql> USE sampledb; mysql> CREATE TABLE sample_table(id INT AUTO_INCREMENT, name VARCHAR(10), PRIMARY KEY(id));
テーブル一覧を表示してsample_tableが作られているか確認してください。
mysql> SHOW TABLES;
まずはDBに接続します。
package main
import (
"fmt"
"github.com/ziutek/mymysql/mysql"
_ "github.com/ziutek/mymysql/thrsafe"
"os"
)
/*
エラーを検出する
*/
func checkError(err error) {
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
/*
エラーを検出し、実行結果を返す
*/
func checkedResult(rows []mysql.Row, res mysql.Result, err error) ([]mysql.Row, mysql.Result) {
checkError(err)
return rows, res
}
func main() {
proto := "tcp"
addr := "127.0.0.1:3306"
dbname := "sampledb"
table := "sample_table"
var user string
var pass string
fmt.Println("ユーザ名を入力してください")
fmt.Scanln(&user)
fmt.Println("パスワードを入力してください")
fmt.Scanln(&pass)
// 接続情報を作成し、DBに接続する
db := mysql.New(proto, "", addr, user, pass, dbname)
checkError(db.Connect())
fmt.Printf("%sに接続しました\n", dbname)
// 遅延実行でDBを閉じる
defer func() {
checkError(db.Close())
fmt.Println("接続を閉じました")
}()
// SQLを実行する(※後述)
}
ここでポイントはimportに
_ "github.com/ziutek/mymysql/thrsafe"
を含める点です。
「_」が入っているので、使用はしていないのですが、mysql内で使用しており(※1)、ここでimportしないといけなくなっています。
ただ、こっち側では使用しないパッケージなので、「_」を付けてビルドを通せる形にしています。
ちなみに
_ "github.com/ziutek/mymysql/native"
でも良いみたいです。
あと、checkError関数とcheckedResult関数は自分用にMyMySQLからコピーしてきました。
checkedResult関数はSQL文実行で使用しています。
※1
thrsafe.goのinit関数でNew関数をmysqlの方へ差し込んでいます。
こんな使い方が出来るんですね。
■SQL操作 INSERT文
INSERT文の実行は以下のようにします。
/*
INSERT文を実行する
*/
func execinsert(db mysql.Conn, table string, num int) {
// INSERT文作成
sqlstr := "INSERT INTO " + table + " (name) VALUES ('test_%d')"
// Query実行(パラメータは可変)
checkedResult(db.Query(sqlstr, num))
fmt.Println("insertを実行しました")
}
ここでは「test_」に引数のnum(関数呼出し毎にインクリメントしている)を足し合わせたものをnameカラムに設定しています。
SQL文はdb(接続情報)のQuery関数で実行します。第二引数のパラメータは可変になっています。
■SQL操作 SELECT文
SELECT文の実行は以下のようにします。
/*
SELECT文を実行する
*/
func execselect(db mysql.Conn, table string) {
// SELECT文作成
sqlstr := "SELECT * FROM " + table
// Query実行
rows, res := checkedResult(db.Query(sqlstr))
// カラムのマッピング
id := res.Map("id")
name := res.Map("name")
fmt.Println("| id | name |")
for _, row := range rows {
// 結果を1行ずつ表示する
fmt.Printf("| %d | %s |\n", row.Int(id), row.Str(name))
}
}
■SQL操作 UPDATE文
UPDATE文の実行は以下のようにします。
/*
UPDATE文を実行する
*/
func execupdate(db mysql.Conn, table string) {
// トランザクション開始
tr, err := db.Begin()
checkError(err)
// UPDATE文作成
sqlstr := "UPDATE " + table + " SET name='test'"
// UPDATE実行
_, err = tr.Start(sqlstr)
if err != nil {
// UPDATE中に失敗したらロールバックする
tr.Rollback()
fmt.Println("Rollbackしました")
} else {
// 問題なくUPDATEが完了していればコミットする
tr.Commit()
fmt.Println("updateをCommitしました")
}
}
ここではトランザクションを使用しています。
db(接続情報)のBegin関数を実行し、mysql.Transaction(ここではtr)を取得してください。
SQL文を実行する時にトランザクションのStart関数で実行し、実行に失敗(errがnilでない場合)した場合は、
Rollback関数でロールバックします。
正常にSQL文が実行できたらCommit関数でコミットしてください。
■SQL操作 DELETE文
DELETE文の実行は以下のようにします。
/*
DELETE文を実行する
*/
func execdelete(db mysql.Conn, table string) {
// DELETE文作成
sqlstr := "DELETE FROM " + table + " WHERE name='test'"
// Query実行
checkedResult(db.Query(sqlstr))
fmt.Println("deleteを実行しました")
}
これでGoでDBが扱えるようになりましたね!
今回説明したSQL実行関数を http://goo.gl/7R1QR にまとめています。
良かったらご覧ください。
0 件のコメント:
コメントを投稿