database/sqlパッケージのMySQLドライバーであるgo-sql-driver/mysqlを利用してMySQLに接続し、CRUD(create/read/update/delete)を実行してみます。
MySQLはローカル環境に構築し、sample_dbデータベースとusersテーブルを作成しました。あらかじめデータを登録しておきます。
1 2 3 4 5 6 7 8 9 10 |
DROP DATABASE IF EXISTS sample_db; CREATE DATABASE sample_db; USE sample_db; CREATE TABLE users ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name TEXT NOT NULL )DEFAULT CHARACTER SET=utf8; INSERT INTO users (name) VALUES ("太郎"),("花子"),("令和"); |
1 2 3 4 5 6 7 8 9 |
mysql> SELECT * FROM users; +----+--------+ | id | name | +----+--------+ | 1 | 太郎 | | 2 | 花子 | | 3 | 令和 | +----+--------+ |
関連ページ
go-sql-driver/mysqlドライバーをインストールします。
1 |
go get -u github.com/go-sql-driver/mysql |
SELECT
まずはあらかじめ登録していたレコードを全て取得してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) //User is struct type User struct { ID int Name string } func main() { db, err := sql.Open("mysql", "root:pass@tcp(127.0.0.1:3306)/sample_db") if err != nil { panic(err.Error()) } defer db.Close() rows, err := db.Query("SELECT * FROM users") if err != nil { panic(err.Error()) } defer rows.Close() for rows.Next() { var user User err := rows.Scan(&user.ID, &user.Name) if err != nil { panic(err.Error()) } fmt.Println(user.ID, user.Name) } err = rows.Err() if err != nil { panic(err.Error()) } } |
16行目
rootユーザー、パスワードはpassで設定してあります。
30行目
Scan()の引数には、取得するカラムを指定します。
実行します。
1 2 3 4 5 |
$ go run main.go 1 太郎 2 花子 3 令和 |
上記例では複数行のレコードを取得しましたが、1件のレコードのみを取得する場合はQueryRowを利用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) //User is struct type User struct { ID int Name string } func main() { db, err := sql.Open("mysql", "root:pass@tcp(127.0.0.1:3306)/sample_db") if err != nil { panic(err.Error()) } defer db.Close() var user User err = db.QueryRow("SELECT * FROM users WHERE id = ?", 1).Scan(&user.ID, &user.Name) switch { case err == sql.ErrNoRows: fmt.Println("レコードが存在しません") case err != nil: panic(err.Error()) default: fmt.Println(user.ID, user.Name) } } |
26行目
該当するレコードがない場合はsql.ErrNoRowsで判定します。
INSERT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) func main() { db, err := sql.Open("mysql", "root:pass@tcp(127.0.0.1:3306)/sample_db") if err != nil { panic(err.Error()) } defer db.Close() stmtInsert, err := db.Prepare("INSERT INTO users(name) VALUES(?)") if err != nil { panic(err.Error()) } defer stmtInsert.Close() result, err := stmtInsert.Exec("進次郎") if err != nil { panic(err.Error()) } lastInsertID, err := result.LastInsertId() if err != nil { panic(err.Error()) } fmt.Println(lastInsertID) } |
16行目
Prepare()でプリペアードステートメント(Prepared Statements)を利用します。
関連ページ
22行目
Exec()の引数に登録する値を入れて実行しています。
UPDATE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) func main() { db, err := sql.Open("mysql", "root:pass@tcp(127.0.0.1:3306)/sample_db") if err != nil { panic(err.Error()) } defer db.Close() stmtUpdate, err := db.Prepare("UPDATE users SET name=? WHERE id=?") if err != nil { panic(err.Error()) } defer stmtUpdate.Close() result, err := stmtUpdate.Exec("漱石", 1) if err != nil { panic(err.Error()) } rowsAffect, err := result.RowsAffected() if err != nil { panic(err.Error()) } fmt.Println(rowsAffect) } |
27行目
RowsAffected()は更新したレコード数を取得しています。仮に存在しないidや同じnameで更新しようとすると31行目では0(ゼロ)と表示されます。
DELETE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) func main() { db, err := sql.Open("mysql", "root:pass@tcp(127.0.0.1:3306)/sample_db") if err != nil { panic(err.Error()) } defer db.Close() stmtDelete, err := db.Prepare("DELETE FROM users WHERE id=?") if err != nil { panic(err.Error()) } defer stmtDelete.Close() result, err := stmtDelete.Exec(3) if err != nil { panic(err.Error()) } rowsAffect, err := result.RowsAffected() if err != nil { panic(err.Error()) } fmt.Println(rowsAffect) } |
参照ページ