go-sqlite3を使用します。
事前準備は
sqlite3を使用する前の準備【Go】 - 技術向上
に記載しています。
CREATE
var DbConnection *sql.DB
func main() {
DbConnection, err := sql.Open("sqlite3", "./example.sql") // 第1引数はDriver、第2引数はデータベース名
if err != nil {
log.Fatalln(err)
}
defer DbConnection.Close() // 必ず閉じる
// バッククォートを使うことで複数行記載できる
// 主キーにidを設定。INTではなくINTEGERである必要がある
cmd := `CREATE TABLE IF NOT EXISTS person (
id INTEGER primary key,
name STRING,
age INT)`
_, err = DbConnection.Exec(cmd) // 戻り値resultは使用しないため破棄
if err != nil {
log.Fatalln(err)
}
}
上記作成したテーブルは、下記コマンドで確認できます。
sqlite> .table // テーブル一覧を取得 sqlite> .schema // 全テーブルの構造を取得 sqlite> .schema person // テーブルpersonの構造を取得
INSERT
var DbConnection *sql.DB
func main() {
DbConnection, err := sql.Open("sqlite3", "./example.sql") // 第1引数はDriver、第2引数はデータベース名
if err != nil {
log.Fatalln(err)
}
defer DbConnection.Close() // 必ず閉じる
cmd := `INSERT INTO person (name, age) VALUES (?, ?)` // SQLInjectionを回避するため、後から指定するものはPrintfではなく、?で指定
_, err = DbConnection.Exec(cmd, "Mike", 25)
if err != nil {
log.Fatalln(err)
}
}
コマンドで、テーブルの中身を検索できます。
sqlite> select * from person;
UPDATE
var DbConnection *sql.DB
func main() {
DbConnection, err := sql.Open("sqlite3", "./example.sql") // 第1引数はDriver、第2引数はデータベース名
if err != nil {
log.Fatalln(err)
}
defer DbConnection.Close() // 必ず閉じる
cmd := `UPDATE person SET age = ? WHERE name = ?`
_, err = DbConnection.Exec(cmd, 26, "Mike")
if err != nil {
log.Fatalln(err)
}
}
DELETE
var DbConnection *sql.DB
func main() {
DbConnection, err := sql.Open("sqlite3", "./example.sql") // 第1引数はDriver、第2引数はデータベース名
if err != nil {
log.Fatalln(err)
}
defer DbConnection.Close() // 必ず閉じる
cmd := `DELETE FROM person WHERE name = ?`
_, err = DbConnection.Exec(cmd, "Mike")
if err != nil {
log.Fatalln(err)
}
}
SELECT
対象のもの全てを抽出するパターン
var DbConnection *sql.DB
type Person struct {
ID int
Name string
Age int
}
func main() {
DbConnection, err := sql.Open("sqlite3", "./example.sql") // 第1引数はDriver、第2引数はデータベース名
if err != nil {
log.Fatalln(err)
}
defer DbConnection.Close() // 必ず閉じる
cmd := `SELECT * FROM person WHERE age = ?`
rows, err := DbConnection.Query(cmd, 26) // 対象全件取得の場合は、Queryを使用
defer rows.Close()
var pp []Person
if err != nil {
log.Fatalln(err)
}
for rows.Next() {
var p Person // 取得結果1件ずつを格納する入れ物を用意
_ = rows.Scan(&p.ID, &p.Name, &p.Age) // Scan()の中身に結果をコピー(値変更のためポインタ渡し)。返り値errorは使用しないため、破棄。forループ終了後、まとめてエラー処理をする
pp = append(pp, p)
}
err = rows.Err() // forループ終了後にまとめてエラーハンドリング
if err != nil {
log.Fatalln(err)
}
for _, v := range pp {
fmt.Println(v)
}
}
対象のものから最初の1件を抽出するパターン
var DbConnection *sql.DB
type Person struct {
ID int
Name string
Age int
}
func main() {
DbConnection, err := sql.Open("sqlite3", "./example.sql") // 第1引数はDriver、第2引数はデータベース名
if err != nil {
log.Fatalln(err)
}
defer DbConnection.Close() // 必ず閉じる
cmd := `SELECT * FROM person WHERE age = ?`
row := DbConnection.QueryRow(cmd, 26) // 対象1件取得の場合は、QueryRowを使用
var p Person // 取得結果を格納する入れ物を用意
err = row.Scan(&p.ID, &p.Name, &p.Age) // Scan()の中身に結果をコピー(値変更のためポインタ渡し)
if err != nil { // 1件でありforループは無いため、ここでエラーハンドリング
if err == sql.ErrNoRows { // errorは、取得対象が存在しないことを識別できる
log.Println("No row")
} else {
log.Fatalln(err)
}
}
fmt.Println(p)
}
補足 - テーブル名のコード内指定について
仕様上、テーブル名に「?」を使用することが、現時点ではできません。
テーブル名を変数として持たせるには、fmt.Sprintf()を使います。
... var tableName = "person" cmd := fmt.Sprintf(`SELECT * FROM %s`, tableName) rows, err := DbConnection.Query(cmd) ...