LoginSignup
4
1

More than 3 years have passed since last update.

[Golang]標準のsqlパッケージで、とりあえずMySQLを操作してみたサンプル

Last updated at Posted at 2019-09-04

いきなり結論のコード

package main

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

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

    defer db.Close()

    fmt.Println("接続成功")

    rows, err := db.Query("SELECT id, last_name, email FROM users limit 10")
    if err != nil {
        panic(err.Error())
    }

    for rows.Next() {
        var id int
        var last_name string
        var email string
        if err := rows.Scan(&id, &last_name, &email); err != nil {
            log.Fatal(err)
        }
        fmt.Println(id, last_name, email)
    }

}
実行結果
接続成功
1 柴咲 shibasaki_asahi@example.com
2 沢村 sawamura_keisuke@example.com
3 阿部 abe_atsuko@example.com
4 佐古 sako_shouta@example.com
5 宮里 miyazato_hitori@example.com
6 梅沢 umezawa_kaori@example.com
7 松村 matsumura_tamaki@example.com
8 高岡 takaoka_houshi@example.com
9 大下 ooshita_yonezou@example.com
10 西岡 nishioka_masaya@example.com

DBにあらかじめ仕込んでおいた、データが取得できました。
(※データ自体はサンプルです。)

解説

github.com/go-sql-driver/mysqlでドライブをインポート

この部分
import (
    "database/sql"
    "fmt"
    "log"
    _ "github.com/go-sql-driver/mysql"
)
  • インポートに、忘れてはならないのが_ "github.com/go-sql-driver/mysql"
  • これはドライバなので、ないとmysqlを取り扱えない
    • 後日、xormという便利なライブラリを使ってみたのですが、こういったライブラリを使った場合も必要だった

(xormを使ってみた記事はこちら。)

また、このように_を書いてインポートする方法は、ブランクインポート(blank import)と呼ばれるそうです。
今回のように、このドライバを初期化させて使いたいだけの場合、定番でこういった使われ方をしています。

sql.Open()で接続

この部分
db, err := sql.Open("mysql", "root:password@/mydb")
  • データベースに接続する関数
  • エラーも返してくれる
  • 接続して、変数に代入する。
  • 引数に、データベースの種類とデータベース情報を渡す
    • データベース情報には、user_namepasswordhostportdb_nameが必要

今回は、ローカルホストへの接続だったので省略していますが、本来は
sql.Open("mysql", "root:password@http://hoge.com/mydb")
みたいな感じになります。

忘れずにdb.Close()でクローズ

この部分
defer db.Close()

忘れる前に、クローズも書いておきます。
deferで最後に実行されます。

Query()で生SQLクエリを実行

この部分
rows, err := db.Query("SELECT id, last_name, email FROM users limit 10")
  • db変数には、先ほどの接続結果が入っている
  • エラーを返してくれる
  • 結果はさらにrowsに代入
  • 引数には、そのままの生SQL文でOK
  • この関数で列ごとにデータを取ってきて、後に出てくるScan関数でマッピングする

Next()で行セットに対して繰り返し処理

この部分
for rows.Next() {
        var id int
        var last_name string
        var email string
        if err := rows.Scan(&id, &last_name, &email); err != nil {
            log.Fatal(err)
        }
  • 行セットに対して繰り返し処理をしている

Scan()取得してきたデータを変数へ

この部分
for rows.Next() {
        var id int
        var last_name string
        var email string
        if err := rows.Scan(&id, &last_name, &email); err != nil {
            log.Fatal(err)
        }
  • Query関数で列ごとに取得してきたデータをこの関数でマッピングする
    • カラムを変数へ読み込んでいる

log.Fatal()でエラーメッセージとともにプログラムを終了させる

この部分
for rows.Next() {
        var id int
        var last_name string
        var email string
        if err := rows.Scan(&id, &last_name, &email); err != nil {
            log.Fatal(err)
        }
  • 詳しい説明はこの記事を参照してみてください。
  • ログメッセージを出力した後、os.Exit(1)を呼び出してプログラムを終了させるそうな

さいごに

ながながと書いてしまいましたが、最期までありがとうございました。
また、何か間違い等あればツッコミ頂ければ幸いです!

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1