こんにちは。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 件のコメント:
コメントを投稿