自由気ままにブログ

地方零細企業プログラマがひっそりとなにかしています。

go-sqlite3をちょっこと触る

f:id:nono138:20200421225921p:plain

プログラミング言語の基礎を学んだ後に、次のステップとして触るのがデータベースになります。

今あるソフトウェア開発でデータベースを扱うのが大半だと思います。
今回は、データベースのテーブル作成・データの挿入・データの参照まで軽く書いて見ました。

ドライバーはmattnさんのgo-sqlite3を使わせて頂きました。

先ずは、sqliteからダウンロードしましょう。



ドライバーはGitHubから、直接ダウンロードするのも良いですが、dosプロンプトを開いてコマンドを叩けば落とせるので試してみて下さい。

コマンド
go get github.com/mattn/go-sqlite3
でダウンロード出来るはずです。(便利ですね~)

今回使うドライバーはgcc(C言語コンパイラ)が必要なのでそちらもダウンロードします。



データベースを確認する為に、DB Browserも一応、入れておきます。


長くて申し訳ありませんが、これで準備は出来ました。

goソース

package main

import (
    "database/sql"
    "fmt"
    "time"

    _ "github.com/mattn/go-sqlite3"
)

//データベース用構造体
type Userinfo struct {
    chord      int
    userName   string
    category   string
    recordDate *time.Time
}

func main() {

    //データベースのコネクション
    DBerr := sql.Open("sqlite3""sample.db")
    if err != nil {
        fmt.Println(err)
    }
    //必ずデータベースは閉じるようにしておきましょう
    defer DB.Close()

    err = createTable(DB)
    if err != nil {
        fmt.Println(err)
    }
    err = insertDB(DB)
    if err != nil {
        fmt.Println(err)
    }
    err = selectDB(DB)
    if err != nil {
        fmt.Println(err)
    }
}


データベースのデータを格納する為の構造体を用意してあげましょう。
構造体とデータベースの型はきちんと合わせてあげましょう。
メインでデータベースを開きます。
コメントでも書いてありますが、必ずデータベースを閉じるようにしましょう。
あとは、関数を読んでいるだけになります。

crateTable

//テーブルの作成
func createTable(DB *sql.DB) (err error) {
    //ユーザー情報テーブル作成
    var cmd = ""
    cmd = "CREATE TABLE userinfo("
    cmd += "Chord INT(8) NOT NULL PRIMARY KEY, "
    cmd += "UserName VARCHAR(24) NOT NULL, "
    cmd += "Category VARCHAR(2) NOT NULL, "
    cmd += "RecordDate DATETIME "
    cmd += ")"

    _err = DB.Exec(cmd)
    if err != nil {
        return err
    }
    return nil
}


sql文を用意して、Execで実行してあげるだけです。
DB Browserで作れているか、一応、確認。
実行前
brow2
作れていますね。
これは、crateTablel関数を呼び出しただけの動作なので、二回目以降は同じテーブルは付く無いので注意してください。

insertDB

//テーブルにデータ挿入
func insertDB(DB *sql.DB) (err error) {
    nowtime := time.Now()
    var cmd = ""
    cmd = "INSERT INTO userinfo("
    cmd += "Chord, UserName, Category, RecordDate) "
    cmd += "VALUES ("
    cmd += "1, 'テスト 太郎', '男性',"
    cmd += nowtime.Format(layout)
    cmd += ")"

    _err = DB.Exec(cmd)
    if err != nil {
        return err
    }
    return nil
}

const layout = "20060102"


こちらも、テーブルを作成する時と、全く同じですね。

brow3
ちゃんと挿入されていますね。

//テーブルのデータを一括検索
func selectDB(DB *sql.DB) (err error) {
    //テーブルデータ取得
    cmd := "SELECT * FROM userinfo"
    rows_ := DB.Query(cmd)

    defer rows.Close()

    var userArray []Userinfo
    for rows.Next() {
        var user Userinfo
        err := rows.Scan(&user.chord, &user.userName, &user.category, &user.recordDate)
        if err != nil {
            fmt.Println(err)
        }
        userArray = append(userArray, user)
    }
    for _user := range userArray {
        fmt.Println(user.chord, user.userName, user.category, user.recordDate)
    }
    return nil
}


今回は*で検索していますが、本番ではちゃんとカラム名を指定してあげましょう。
Scanで、構造体にデータを挿入してあげます。
あとは、配列に入れて、その配列をデバック用にoutputしています。
配列に入れることで、行単位でデータを取れるので、後々楽だったりします。

実行結果 (省きましたが、insertをもう一回走らせています)
dos

DB Browser

brow4

dosプロンプト上だと、レコードが上手くとれていませんね。
DB Browserだと上手く表示出来ているんですけどね。
原因として考えれるのは、sqliteがDATETIME型をサポートしていないので、TEXT型で入れてstring型で受け取ってあげるのが良いかもです。

データベースもいろんな選択肢がありますが、シンプルながら一連の基礎まで使えるsqliteを採用しました。
実際、sqliteスマホゲームや、比較的軽いデータを扱うwebサービスでも採用されていますので、機能としては十分だと思います。
金融関係だと、Oracleがまだ、主流らしいですけが、まだ触ったことないのでそこら辺は分かりません

web系で、サーバサイドを考えている方はSQLは必ず通る道です。
Goだけやってればいいとは限らないのがツライところですね

最近では、javaScriptのnode.jsでサーバサイドもやってしまうと言った動きもあるそうなので、フロントエンドの方も「ちょっと、node.jsでサーバサイドやってみて」と無茶振りされるかもしれないので、データベース周りは知ってて損は無いと思います。