Go web 12. SQLite3

4349 ワード

SQLite 3とは?


SQLiteは、MySQLやPostgreSQLなどのデータベース管理システムですが、サーバではなくアプリケーション用の比較的軽いデータベースです.
従来のリレーショナル・データベースと比較して、大規模な作業には適していませんが、中小規模のデータベースであれば、速度は劣りません.また、APIは、1つのファイルのみを使用してデータを格納することを特徴とするライブラリのみを呼び出す.ウィキペディア-
つまり、MySQL、MySQL、OracleDBには、データベースをインストールおよび実行するサーバが必要です.
ただし、SQLiteは簡単なファイルのみを使用します.

tdm-gccの取り付け


Go言語でSQLiteを使用する場合、go-sqlite 3という外部パッケージが使用されます.
このときGo言語でCGo機能が使用されます.これはC言語のライブラリを使用することを意味します.
しかし、問題は標準C言語をコンパイルできることであり、標準C言語をコンパイルするには標準コンパイラが必要であることである.
標準コンパイラでは、Go言語はgccを使用します.
しかし、MS WindowsではLinuxベースのgccはサポートされていない.
しかし、MS Windowsでもgccを動かすことができる環境があります.それがMinGWです.
したがって、MS WindowでLinux標準コンパイラを使用するには、MinGWを使用して環境を作成し、gccを使用する必要があります.

簡単に言えば、tdm-gccをインストール!


https://jmeubank.github.io/tdm-gcc/download/
上のアドレスに接続してダウンロードしてインストールします

実行minGW

go-sqlite 3のインストール
go get github.com/mattn/go-sqlite3

SQLite 3の使用


web 10.SQLite 3をtodoリストに適用します。


ex) model.go
package model

import (
	"time"
)

type Todo struct {
	ID        int       `json:"id"`
	Name      string    `json:"name"`
	Completed bool      `json:"completed"`
	CreatedAt time.Time `json:"created_at"`
}

// 인터페이스 생성
type dbHandler interface {
	getTodos() []*Todo
	addTodo(name string) *Todo
	removeTodo(id int) bool
	completeTodo(id int, complete bool) bool
}

// 인터페이스의 인터페이스를 가지고 있음
var handler dbHandler

func init() {
	// handler = newMemoryHandler()
	handler = newSqliteHandler()
}

func GetTodos() []*Todo {
	return handler.getTodos()
}

func AddTodo(name string) *Todo {
	return handler.addTodo(name)
}

func RemoveTodo(id int) bool {
	return handler.removeTodo(id)
}

func CompleteTodo(id int, complete bool) bool {
	return handler.completeTodo(id, complete)
}
ex) memoryHandler.go
package model

import "time"

// 기존의 메모리 맵을 별도 스트럭터로 만듦
type memoryHandler struct {
	todoMap map[int]*Todo
}

// memoryHandler의 메서드
func (m *memoryHandler) getTodos() []*Todo {
	list := []*Todo{}
	for _, v := range m.todoMap {
		// map의 인덱스 만큼 반복
		// 키는 받지않고 value만 받음
		list = append(list, v)
		// list에 v값을 어팬드
	}
	return list
}

func (m *memoryHandler) addTodo(name string) *Todo {
	id := len(m.todoMap) + 1                   // map의 갯수만큼 id
	todo := &Todo{id, name, false, time.Now()} // 포인터형 구조체 Todo를 생성
	m.todoMap[id] = todo                       // todo의 데이터를 맵에 넣음
	return todo
}

func (m *memoryHandler) removeTodo(id int) bool {
	if _, ok := m.todoMap[id]; ok {
		delete(m.todoMap, id)
		return true
	}
	return false
}

func (m *memoryHandler) completeTodo(id int, complete bool) bool {
	if todo, ok := m.todoMap[id]; ok { // 맵에 있는지 확인
		todo.Completed = complete // 맵에 있는경우 변경
		return true
	}
	return false
}
func newMemoryHandler() dbHandler {
	m := &memoryHandler{}
	m.todoMap = make(map[int]*Todo)
	return m
}
ex) sqliteHandler.go
package model

import (
	"database/sql"
	"os"

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

type sqliteHandler struct {
	db *sql.DB
}

func (s *sqliteHandler) getTodos() []*Todo {
	return nil
}

func (s *sqliteHandler) addTodo(name string) *Todo {
	return nil
}

func (s *sqliteHandler) removeTodo(id int) bool {
	return false
}

func (s *sqliteHandler) completeTodo(id int, complete bool) bool {
	return false
}

// 데이터 베이스를 열면 사라지기전에 닫아줘야함
func (s *sqliteHandler) close() {
	s.db.Close()
}

func newSqliteHandler() dbHandler {
	os.Remove("./test.db")
	database, err := sql.Open("sqlite3", "./test.db")
	if err != nil {
		panic(err)
	}
	statement, _ := database.Prepare(
		`CREATE TABLE IF NOT EXISTS todos (
			id        INTEGER  PRIMARY KEY AUTOINCREMENT,
			name      TEXT,
			completed BOOLEAN,
			createdAt DATETIME
		)`) // 테이블을 만드는 쿼리문
	statement.Exec()
	return &sqliteHandler{db: database}
}