GoでMysqlに接続してselect・update・deleteしようか

f:id:utr066:20181222184550p:plain

Goでmysqlに接続してみよう。

mysqlを使う

まあmysql使うことも多いと思うからmysqlに接続しよう。今回は、ローカルに入れたmysqlにgoで接続してごにょごにょしたい。mysqlを入れていない人は入れておこう。

brewで入れておきましょうか。homebrew以外で入れる方は頑張ってください。

$ brew install mysql
$ mysql -uroot

多分最初はpassword指定なしのrootで入れると思うから、接続の確認しておきましょう。接続できたらdatabaseとtableを作成して少しデータを入れておきます。Goからいじるためですね。

mysql>となったらそこで以下のコマンドを打ちます。

$ create database sample;
$ use sample;
$ create table users(id int, name varchar(10));
$ show tables;
// usersができていることを確認
$ insert into users (id, name) values (1, '太郎'), (2, 'hoge'), (3, 'fuga')
// とりあえず3人ほどuserを作ります
$ select * from users;
作られたか確認しましょう。

mysqlにデータが保存できたら準備完了です。このデータをGoでいじりましょう。

goでusersテーブルにアクセスする

go/src配下で適当なディレクトリを作ります。まあsampleとしておきましょう。

$ mkdir sample

作ったら配下にmain.goを作ります。

sample
.
└── main.go

このmain.goにDBに接続する処理を書いていきますか。

接続を確認する

まずは、DBに接続できるか確認しておきましょう。

import (
  "database/sql"
  _ "github.com/go-sql-driver/mysql"
  "log"
)

func main() {
  db, err := sql.Open("mysql", "root:@/sample")
  if err != nil {
    panic(err.Error())
  }
  defer db.Close()

  if err = db.Ping(); err != nil {
    log.Fatalf("接続が確認できなかったよ!やったね!!")
  }
}

接続できなかった場合、log.Fatalf内部の文が出力されるはずです。試しにsql.Openの引数で指定したデータベース名をSampleではなく別のものにしてみると、出力されるのがわかるのではないでしょうか。

usersテーブルからデータを取得しよう

次はさっき作ったusersテーブルから保存されているデータを取得したいです。

こちらに書いてあるコードを使わせていただきます。

dev.classmethod.jp

package main

import (
  "database/sql"
  "fmt"
  _ "github.com/go-sql-driver/mysql"
)

func main() {
  // DBへの接続
  db, err := sql.Open("mysql", "root:@/sample")
  if err != nil {
    panic(err.Error())
  }
  // 接続を閉じる
  defer db.Close()

  if err = db.Ping(); err != nil {
    log.Fatalf("接続が確認できなかったよ!やったね!!")
  }

  rows, err := db.Query("SELECT * FROM users")
  if err != nil {
    panic(err.Error())
  }

  for rows.Next() {
      var id int
      var name string
      if err := rows.Scan(&id, &name); err != nil {
          panic(err.Error())
      }
      fmt.Println(id)
      fmt.Println(name)
      // idとnameが表示されるはず。
  }
}

やっていることとしては、さっき作ったDBに接続して、SELECT * FROM usersした結果に対して処理を行なっている。その処理っていうのが、for rows.Next()の中身。取ってきたデータに対してrows.Scanしてidとnameを表示させている。

insertしよう

DBからデータを取得するだけでは物足りません。なので、Goでデータをusersテーブルに挿入してみましょう。 以下の文を追加して実行してみるとどうなるでしょう。

_, err = db.Exec("insert into users (id, name) values (4, 'ほげ')")
if err != nil {
    log.Fatalf("db.Exec(): %s\n", err)
}

実際にinsertされたかをみてみます。

mysql> select * from users;
+------+--------+
| id   | name   |
+------+--------+
|    1 | 太郎   |
|    2 | hoge   |
|    3 | fuga   |
|    4 | ほげ   |
+------+--------+

idが4のuserが入っていますね。

deleteしよう

普通にExecの引数にsql書けばいけますね。

  _, err = db.Exec("delete from users where id=4")
    if err != nil {
        log.Fatalf("db.Exec(): %s\n", err)
    }

updateしよう

同様にですね。

_, err = db.Exec("update users set name = 'changed' where id=3")
if err != nil {
    log.Fatalf("db.Exec(): %s\n", err)
}
mysql> select * from users;
+------+---------+
| id   | name    |
+------+---------+
|    1 | 太郎    |
|    2 | hoge    |
|    3 | changed |
+------+---------+

prepare使ったほうがいいらしい

prepare使ったほうがいいらしいね。

dsas.blog.klab.org