go langを勉強し始めて、何かappを作れないかと思っていたので簡単なcrudのapp作成に打ち込みました。
下準備
まず、始めるに当たって、go langの基礎を学んでおく必要があるかと思います。
go langのinstallはやっておいてください
goの構文や概念の理解
slice,struct,型決め,変数の定義などなど。基礎的なところで大丈夫かと思います。(自分もそんなになので)
tree構造
todo/ (root)
├handle
┃ └ handle.go
┣serv
┃ └ data.go
┣database
┃ └ db.go.go
┃
└ main.go
└ index.html
└ new.html
こんなんです。
handleはhttpのリクエスト処理の役割
servはdbから情報を引っ張ってきたりする役割
databaseはdbと繋げる役割
serverを立ち上げる
package main
import (
"net/http"
"./handle" //同じ構造上を参照するときには./で表現
)
func main() {
http.HandleFunc("/", handle.Showindex) //index.htmlを表示
err := http.ListenAndServe(":3000", nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
package handle
import (
"net/http"
"net/url"
"text/template"
"../serv" //一つ上の構造を参照するには../で表現。
)
func Showindex(w http.ResponseWriter, r *http.Request) {
tem, _ := template.ParseFiles("index.html")
// p := serv.Connected() databaseの接続で使いますので今はコメントアウト。
p:= 1 (仮置き)
tem.Execute(w, p)
//execute templateを動かす。
}
net/http packageを使って、serverを立ち上げています。
もし、立ち上げられなかったら、qiitaや、公式を見てもいいかもしれません。
https://golang.org/pkg/net/http/
go run main.go
を打ち込んで実行。
urlはlocalhost:3000です。
これで、index.htmlに書いてあるものが表示されればokです。
余談ですが、cssを当てるときには、
http.Handle("/stylesheet/", http.StripPrefix("/stylesheet/", http.FileServer(http.Dir("stylesheet/"))))
のような記述が必要になってきます。以下参照
https://qiita.com/Sekky0905/items/fca9d9118ef23bf24791
databaseから情報を引っ張ってくる
みなさん、まずはdatabaseを作ってください。(マグマスパゲッティ風)
今回は、mysqlの接続方法を採用しました!
db nameはmydbです。 passwordは""です。空です。
カラムはid,body,image,created_at,updated_atです。
主にservとdatabaseが重要ですかね。
handle/handle.goで p := serv.Connected()があると思います。
これはserv packageのConnected functionを呼び出しています。コメントアウトを外してConnected funcを呼び出しましょう。
以下は、そのserv.Connected funcの定義です。
package serv
import (
"log"
"time"
"fmt"
"../database"
)
type Vertex struct { //for save
Id int
Body string
Image string
Created_time time.Time
Updated_time time.Time
}
func Connected() []Vertex { //2重slice 全件取得
db := database.ConnectDB()
defer db.Close()
//sql
rows, err := db.Query(`SELECT id,body,image,created_at,updated_at FROM posts`)
if err != nil {
log.Fatal(err)
}
var sli []Vertex
var v1 Vertex //structをv1で使用する宣言
for rows.Next() { //nextはscanを使う為に必要
if err := rows.Scan(&v1.Id, &v1.Body, &v1.Image, &v1.Created_time, &v1.Updated_time); err != nil {
log.Fatal(err)
}
//rowsに入れたクエリをscanで実行。scanしたものをVertex structに入れ込む処理。
sli = append(sli, v1)
}
fmt.Println(sli)
return sli
//sliは{[id:1,body:bbb,image:fff,created_at:2019-0101,updated_at:2019-0101]}とかで帰ってきたはず。
}
package database
import (
"database/sql"
"log"
_ "github.com/go-sql-driver/mysql"
//sql: unknown driver "mysql" (forgotten import?)と言われるので _を使用
)
var db *sql.DB
func ConnectDB() *sql.DB {
db, err := sql.Open("mysql", "root:@/mydb")
//userはroot, passwordはなし,dbnameはmydb
if err != nil {
log.Fatalf("Could not open db: %v", err)
}
//if err != nil {
// log.Fatal(err)
//}
//return db 上のエラーハンドリングとほぼ同義。
}
Connected funcがかけました。
ここではstruct(構造体)を定義し、その構造体にdatabaseから引っ張ってきた情報を入れて返す処理を行なっています。
db := database.ConnectDB() defer db.Close()
これは、dbと繋げる処理を担うもので変数dbにdatabseの情報を入れます。database/db.goにfuncの定義があります。dbはopenしたらcloseするのを忘れずに。
https://github.com/go-sql-driver/mysql
db.QueryはQuery methodを用いてクエリ処理を行います。
https://golang.org/pkg/database/sql/#DB.Query
しかし、ここではあくまでクエリの準備段階です。
実際にクエリが走るのは
if err := rows.Scan(&v1.Id, &v1.Body, &v1.Image, &v1.Created_time, &v1.Updated_time)
この部分です。
構造体に入れたものをsliceで囲み、そのsliceを返り値として返します。
これで、dbから情報を引っ張って来れましたね。
取得した情報をtemplateに表示させるためには{{.}}が必要です。
https://qiita.com/tetsuzawa/items/0d043ad76b9705cdbb79
part 2へ
https://qiita.com/dossy/items/17cd49bd654e59dd26e2
色々書くと、見ずらくなったりするので分割することにしました。