5
6

More than 3 years have passed since last update.

【Golang】データベース操作 sqlite3

Posted at

【Golang】データベース操作 sqlite3

Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。

package main

/*
sqliteをインストールする際の手順の確認

PostgreSQL は次回。ほぼ同じだが。

インストール済
https://qiita.com/__init__/items/2edfc7acf11234e5b1aa

Mac
# brew のインストール
-> https://brew.sh/index_ja

# sqlite3 をインストール
brew install sqlite

Install gcc C言語のライブラリをインポートするので、GOがビルドする際に必要
-> https://developer.apple.com/xcode

# ドライバのインストール
go get github.com/mattn/go-sqlite3

# 不要だが一応
export CGO_ENABLED=1

Windows
Install sqlite3
-> https://www.sqlite.org/download.html

Install gcc
-> http://tdm-gcc.tdragon.net/

# ドライバのインストール
go get github.com/mattn/go-sqlite3

# 不要だが一応
set CGO_ENABLED=1

macでバージョン確認
# sqlite3 インストール確認
$ sqlite3
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
# sqlite3 を抜ける
sqlite> .exit

# xcode のコマンドラインツールの確認
$ xcode-select --install
xcode-select: error: command line tools are already installed, use "Software Update" to install updates

# gcc インストール確認
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin


//データベース操作


*/

import (
    "database/sql"
    "fmt"
    "log"

    //インポート _にしないとコンパイルエラーになる。使用しない為
    _ "github.com/mattn/go-sqlite3"
)

var DbConnection *sql.DB

type Person struct {
    Name string
    Age  int
}

func main() {
    //1
    //DBを開く  なければ作成される
    DbConnection, _ := sql.Open("sqlite3", "./example.sql")
    //終わったら閉じる
    defer DbConnection.Close()
    //DB作成 SQLコマンド
    cmd := `CREATE TABLE IF NOT EXISTS person(
        name STRING,
        age  INT)`

    //実行 結果は返ってこない為、_にする
    _, err := DbConnection.Exec(cmd)

    //エラーハンドリング
    if err != nil {
        fmt.Println("エラー")
        log.Fatalln(err)
    }

    //ターミナル
    //sqlite3
    //.table
    //SELECT * FROM tablename;
    //で確認

    //2 CRUD処理
    //Create
    //データを追加
    //VALUES (?, ?)  値は後で渡す。セキュリテイの関係でこのようにする方がいい
    //SQLインジェクション 悪意あるコマンドでDBが操作されてしまうのを防ぐ ?でエスケープしてくれる
    cmd = "INSERT INTO person (name, age) VALUES (?, ?)"
    //実行
    //レコードを取得する必要のない、クエリはExecメソッドを使う
    //第二引数からは、コマンド?部の値
    _, err = DbConnection.Exec(cmd, "Nancy", 20)
    if err != nil {
        log.Fatalln(err)
    }

    //Update
    //データの更新 Mike が存在する場合
    cmd = "UPDATE person SET age = ? WHERE name = ?"
    _, err = DbConnection.Exec(cmd, 25, "Mike")
    if err != nil {
        log.Fatalln(err)
    }

    //Read
    //Get  All
    //マルチセレクト
    //データ全てをループで表示
    //Queryは全て取得する
    cmd = "SELECT * FROM person"
    rows, _ := DbConnection.Query(cmd)
    defer rows.Close()
    //structを作成
    var pp []Person
    //取得したデータをループでスライスに追加 for rows.Next()
    for rows.Next() {
        var p Person
        //scan データ追加
        err := rows.Scan(&p.Name, &p.Age)
        if err != nil {
            log.Println(err)
        }
        pp = append(pp, p)
    }
    err = rows.Err()
    if err != nil {
        log.Fatalln(err)
    }
    //表示
    for _, p := range pp {
        fmt.Println(p.Name, p.Age)
    }

    //特定のデータを取得
    cmd = "SELECT * FROM person where age = ?"
    //age = 20にして実行
    //QueryRowは最初の一件だけ取得する。
    row := DbConnection.QueryRow(cmd, 20)
    var p Person
    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)

    //Delete
    //データの削除  全て
    cmd = "DELETE FROM person WHERE name = ?"
    _, err = DbConnection.Exec(cmd, "Nancy")
    if err != nil {
        log.Fatalln(err)
    }

    //マルチセレクト  テーブルもSQLインジェクション対策
    //こちらを推奨
    //データを構造体に入れて表示
    //テーブルはSQLインジェクション対策が使えない
    tableName := "person"
    //テーブル名指定は?が使えない為、%sを使う。
    //後に対応されるかも?
    cmd = fmt.Sprintf("SELECT * FROM %s", tableName)
    rows1, _ := DbConnection.Query(cmd)
    defer rows1.Close()
    var pp1 []Person
    //パターンとして覚える
    for rows1.Next() {
        var p Person
        //データを構造体に追加
        err := rows1.Scan(&p.Name, &p.Age)
        if err != nil {
            log.Println(err)
        }
        //ppに追加
        pp1 = append(pp1, p)
    }
    //まとめてエラーチェック
    err = rows1.Err()
    if err != nil {
        //エラーなら終了
        log.Fatalln(err)
    }
    for _, p := range pp1 {
        fmt.Println(p.Name, p.Age)
    }
}

5
6
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
5
6