💻
Go言語環境構築DB接続DB操作/おまけHelloWorld
前提
https://a.r10.to/hPLPuw
書籍を元に少し値や名を変えて手を動かしております。
入門者のためコメントアウトをして定着させるための記事化でありコメントアウトが多々。未経験Goに触れてみたい方の参考になればと思う反面2次情報のため鵜吞みにせず公式ドキュメントを基準に参考頂けますと幸いです。
環境構築
・SQLlite
sqlite-dll-win-x64-3490100.zip
・コンパイルツールgcc
stdm64-gcc-10.3.0-2.exebash
gcc --version
・Go install
go version・Git (Win) install
・VSCode (Win) install
拡張:「Jpanese Languge Pack for」「Go」
go.mod 作成
go mod init awesomeProject
go get github.com/mattn/go-sqlite3
Hello.go
package main
import "fmt"
func main() {
fmt.Println("HelloWorld")
}
bash
go run Hello.go
//HelloWorld
・DB接続
lesson.go
package main
import (
"database/sql"
"log"
_ "github.com/mattn/go-sqlite3"
)
var DbGate *sql.DB //sql.db の変数宣言。 database/sql パッケージにある DB 型を指す。
func main() {
DbGate, _ := sql.Open("sqlite3", "./example.sql") //sql.Open関数でDB開く。 _ はブランク識別子sql.Open のエラー戻り値を無視
defer DbGate.Close() //defer文ファイル閉じ忘れ防止(処理を遅らせて実行)。Closeメソッド
//CREATE作成
cmd := `CREATE TABLE IF NOT EXISTS budget(
name STRING,
age INT
)`
_, err := DbGate.Exec(cmd) //Execメソッド データベース操作 引数cmd はSQLコマンド「命令そのもの」
if err != nil {
log.Fatalln(err)
}
//INSERT
cmd = "INSERT INTO budget (name,age) VALUES (?,?)" //レコードの追加
_, err = DbGate.Exec(cmd, "MIYA", 20)
if err != nil {
log.Fatalln(err) //重大なエラーを出力して即終了
}
}
bash
go run lesson.go
#実行後example.sqlファイルが作成される
SELECT文で現在の値を取得確認
bash
sqlite3 example.sql
sqlite> select * from budget;
MIYA|20
.exit
lesson.go
_, err = DbGate.Exec(cmd, "cat", 10) //MIYA 20を書き換えてレコード追加
bash
sqlite3 example.sql
sqlite> select * from budget;
MIYA|20
cat|10
.exit
lesson.go
//UPDAATE文
cmd = "UPDATE budget SET age = ? WHERE name =?"
_, err = DbGate.Exec(cmd, 21, "MIYA") //age 20→21にレコード更新
if err != nil {
log.Fatalln(err)
}
再実行
bash
sqlite> select * from budget;
MIYA|21
cat|10
cat|10
sqlite>
lesson.go
package main
import (
"database/sql"
"log"
_ "github.com/mattn/go-sqlite3"
)
var DbGate *sql.DB //sql.db の変数宣言。 database/sql パッケージにある DB 型を指す。
func main() {
DbGate, _ := sql.Open("sqlite3", "./example.sql") //sql.Open関数でDB開く。 _ はブランク識別子sql.Open のエラー戻り値を無視
defer DbGate.Close() //defer文ファイル閉じ忘れ防止(処理を遅らせて実行)。Closeメソッド
//CREATE作成
cmd := `CREATE TABLE IF NOT EXISTS budget(
name STRING,
age INT
)`
_, err := DbGate.Exec(cmd) //Execメソッド データベース操作 引数cmd はSQLコマンド「命令そのもの」
if err != nil {
log.Fatalln(err)
}
cmd = "INSERT INTO budget (name,age) VALUES (?,?)" //レコードの追加
_, err = DbGate.Exec(cmd, "cat", 10) //MIYA 20を書き換えてレコード追加
if err != nil {
log.Fatalln(err) //重大なエラーを出力して即終了
}
//UPDAATE文
cmd = "UPDATE budget SET age = ? WHERE name =?"
_, err = DbGate.Exec(cmd, 21, "MIYA") //age 20→21
if err != nil {
log.Fatalln(err)
}
//DELETE文でレコードを削除
cmd = "DELETE FROM budget WHERE name = ?"
_, err = DbGate.Exec(cmd, "cat")
if err != nil {
log.Fatalln(err)
}
}
SELECT文で1件取得 QueryRowメソッド
構造体を大文字で作成(他のパッケージからアクセス可能)
lesson.go
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
var DbGate *sql.DB //sql.db の変数宣言。 database/sql パッケージにある DB 型を指す。
//構造体の定義BudgetBudget
type Budget struct {
Name string
Age int
}
func main() {
DbGate, _ := sql.Open("sqlite3", "./example.sql") //sql.Open関数でDB開く。 _ はブランク識別子sql.Open のエラー戻り値を無視
defer DbGate.Close() //defer文ファイル閉じ忘れ防止(処理を遅らせて実行)。Closeメソッド
//CREATE作成
cmd := `CREATE TABLE IF NOT EXISTS budget(
name STRING,
age INT
)`
_, err := DbGate.Exec(cmd) //Execメソッド データベース操作 引数cmd はSQLコマンド「命令そのもの」
if err != nil {
log.Fatalln(err)
}
//SELECT文で1件レコードを取得 QueryRowメソッド
cmd = "SELECT * FROM budget WHERE age = ?"
row := DbGate.QueryRow(cmd, 21)
var p Budget
err = row.Scan(&p.Name, &p.Age)
if err != nil {
if err == sql.ErrNoRows {
log.Println("No row")
} else {
log.Println(err)
}
}
fmt.Println(p.Name, p.Age)
bash
go run lesson.go
MIYA 21
全取得の場合の解説Queryメソッド
lesson.go
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
var DbGate *sql.DB //sql.db の変数宣言。 database/sql パッケージにある DB 型を指す。
type budget struct {
Name string
Age int
}
func main() {
DbGate, _ := sql.Open("sqlite3", "./example.sql") //sql.Open関数でDB開く。 _ はブランク識別子sql.Open のエラー戻り値を無視
defer DbGate.Close() //defer文ファイル閉じ忘れ防止(処理を遅らせて実行)。Closeメソッド
//CREATE作成
cmd := `CREATE TABLE IF NOT EXISTS budget(
name STRING,
age INT
)`
_, err := DbGate.Exec(cmd) //Execメソッド データベース操作 引数cmd はSQLコマンド「命令そのもの」
if err != nil {
log.Fatalln(err)
}
//Queryメソッドで全レコード取得
// データベースから全データを取得
cmd = "SELECT * FROM budget" // "budget"表の全部を取る命令を準備
rows, _ := DbGate.Query(cmd) // 命令を実行して結果をrowsに保存(エラーは無視)
defer rows.Close() // 使い終わったらrowsを閉じる予約
var pp []budget // データを集める空のリストを作る
for rows.Next() { // 1行ずつ見ていく
var p budget // 1行分のデータを入れる箱
err := rows.Scan(&p.Name, &p.Age) // データをpにコピー
if err != nil {
log.Println(err) // エラーがあれば記録
}
pp = append(pp, p) // pをリストに追加
}
for _, p := range pp { // リストの中身を全部表示
fmt.Println(p.Name, p.Age) // 名前と年齢を画面に出す
}
}
Queryメソッドで全レコード取得 まとめ
rows.Next() で表のデータを1行ずつ見る。
p に1行分のデータ(例: 太郎, 13)を入れる。
pp = append(pp, p) で、そのデータをスライス(pp)に追加。
全部集めたら、pp を使って表示。
別途おまけHelloWorld
Hello.go ※以降DB接続には触れておりません。
package main
import "fmt"
func main() {
fmt.Println("HelloWorld")
}
net/http利用「localhost:8080」webサーバー立ち上げ
Hello.go ※HelloWorldの書き換え
package main
import (
"log"
"net/http"
)
func viewHandler(w http.ResponseWriter, r *http.Request) {
// レスポンスとして簡単なメッセージを返す
_, err := w.Write([]byte("Hi、直接的な書き込みのviewです"))
if err != nil {
log.Println("レスポンスの書き込み時エラー:", err)
}
}
func main() {
http.HandleFunc("/view/", viewHandler) //http.HandleFunc。viewHandler関数
log.Fatal(http.ListenAndServe(":8080", nil))
}
//http://localhost:8080
//http://localhost:8080/view/test
Discussion