とりあえず、ソースを保存。
備忘用なので、説明は後で。
main.go
package main
import (
"routes"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// 事前にテンプレートをロード 相対パス
router.LoadHTMLGlob("templates/*.html")
// グルーピング
user := router.Group("/user")
{
// Railsのようなマッピングは重複エラーになり不可。
// 更新・削除は、PATCH・DELETEで対応できないので、POST・GETで対応
user.GET("/", routes.Index) // ユーザ一覧
user.GET("/show/:id", routes.Show) // ユーザー参照
user.GET("/new", routes.New) // 新規ユーザー登録
user.POST("/new", routes.Create) // 新規ユーザー作成
user.GET("/edit/:id", routes.Edit) // ユーザー編集
user.POST("/edit/:id", routes.Update) // ユーザー更新
user.GET("/delete/:id", routes.Delete) // ユーザー削除
}
router.Run(":8080")
}
routes/users_controller.go
package routes
import (
"database/sql"
"log"
"net/http"
"github.com/gin-gonic/gin"
_ "github.com/mattn/go-sqlite3"
)
var DbConnection *sql.DB
type Users struct {
Id int
UserId string
Name string
}
func Index(c *gin.Context) {
log.Print("一覧画面")
DbConnection, _ := sql.Open("sqlite3", "./db/sqlite3/test.db") // main.goからのパスを指定
defer DbConnection.Close()
/* テーブルが存在しない場合に作成する
cmd := `CREATE TABLE IF NOT EXISTS m_users(
id integer PRIMARY KEY AUTOINCREMENT,
user_id string,
name string)`
_, err := DbConnection.Exec(cmd)
if err != nil {
log.Fatalln(err)
}
*/
cmd := "SELECT id, user_id, name FROM m_users"
rows, _ := DbConnection.Query(cmd)
defer rows.Close()
var pp []Users // 取得するデータの構造体を用意(複数取得するのでスライス)
for rows.Next() {
var p Users // 取得の格納用
err := rows.Scan(&p.Id, &p.UserId, &p.Name) // Scanで指定した変数に格納
if err != nil {
log.Println(err)
}
pp = append(pp, p)
}
for _, p := range pp {
log.Println(p.Id, p.UserId, p.Name)
}
c.HTML(http.StatusOK, "index", gin.H{"Users": pp})
}
func Show(c *gin.Context) {
log.Print("参照画面")
DbConnection, _ := sql.Open("sqlite3", "./db/sqlite3/test.db") // main.goからのパスを指定
defer DbConnection.Close()
id := c.Param("id") // URLの:idを取得
cmd := "SELECT id, user_id, name FROM m_users where id = ?"
row := DbConnection.QueryRow(cmd, id) // ?の条件にidを指定
// QueryRowの場合、close処理は不要
var p Users
err := row.Scan(&p.Id, &p.UserId, &p.Name) // Scanで指定した変数に格納
if err != nil {
if err == sql.ErrNoRows {
log.Println("No row")
} else {
log.Println(err)
}
}
log.Print(p.Id, p.UserId, p.Name)
c.HTML(http.StatusOK, "show", gin.H{"User": p})
}
func New(c *gin.Context) {
log.Print("登録画面")
c.HTML(http.StatusOK, "new", gin.H{})
}
func Create(c *gin.Context) {
log.Print("登録処理")
DbConnection, _ := sql.Open("sqlite3", "./db/sqlite3/test.db") // main.goからのパスを指定
defer DbConnection.Close()
userid := c.PostForm("userID")
name := c.PostForm("name")
cmd := "INSERT INTO m_users (user_id, name) VALUES (?, ?)"
_, err := DbConnection.Exec(cmd, userid, name)
if err != nil {
log.Fatalln(err)
}
c.Redirect(http.StatusMovedPermanently, "/user")
}
func Edit(c *gin.Context) {
log.Print("編集画面")
DbConnection, _ := sql.Open("sqlite3", "./db/sqlite3/test.db") // main.goからのパスを指定
defer DbConnection.Close()
id := c.Param("id") // URLの:idを取得
cmd := "SELECT id, user_id, name FROM m_users where id = ?"
row := DbConnection.QueryRow(cmd, id) // ?の条件にidを指定
// QueryRowの場合、close処理は不要
var p Users
err := row.Scan(&p.Id, &p.UserId, &p.Name) // Scanで指定した変数に格納
if err != nil {
if err == sql.ErrNoRows {
log.Println("No row")
} else {
log.Println(err)
}
}
log.Print(p.Id, p.UserId, p.Name)
c.HTML(http.StatusOK, "edit", gin.H{"User": p})
}
func Update(c *gin.Context) {
log.Print("更新処理")
DbConnection, _ := sql.Open("sqlite3", "./db/sqlite3/test.db") // main.goからのパスを指定
defer DbConnection.Close()
id := c.Param("id") // URLの:idを取得
userid := c.PostForm("userID") // 画面の値を取得
name := c.PostForm("name") // 画面の値を取得
cmd := "UPDATE m_users SET user_id = ?, name = ? WHERE id = ?"
_, err := DbConnection.Exec(cmd, userid, name, id)
if err != nil {
log.Fatalln(err)
}
c.Redirect(http.StatusMovedPermanently, "/user")
}
func Delete(c *gin.Context) {
log.Print("削除処理")
DbConnection, _ := sql.Open("sqlite3", "./db/sqlite3/test.db") // main.goからのパスを指定
defer DbConnection.Close()
id := c.Param("id") // URLの:idを取得
cmd := "DELETE FROM m_users WHERE id = ?"
_, err := DbConnection.Exec(cmd, id)
if err != nil {
log.Fatalln(err)
}
c.Redirect(http.StatusMovedPermanently, "/user")
}
ビュー
index.html
{{define "index"}}
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<title>一覧</title>
</head>
<body>
<a href="/user/new">新規</a>
<ul>
{{range .Users}}
<li>
{{.Id}} {{.UserId}} {{.Name}}
<a href="/user/show/{{.Id}}">参照</a>
<a href="/user/edit/{{.Id}}">編集</a>
<a href="/user/delete/{{.Id}}" onclick="return confirm(`削除しますか?`)">削除</a>
</li>
{{end}}
</ul>
</body>
</html>
{{end}}
show.html
{{define "show"}}
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<title>参照</title>
</head>
<body>
<ul>
<li>
{{.User.Id}} {{.User.UserId}} {{.User.Name}}
</li>
</ul>
</body>
</html>
{{end}}
edit.html
{{define "edit"}}
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<title>編集</title>
</head>
<body>
<ul>
<form action="/user/edit/{{.User.Id}}" method="POST">
<input type="text" name="userID" value="{{.User.UserId}} ">
<br>
<input type="text" name="name" value="{{.User.Name}} ">
<br>
<input type="submit" value="更新">
</form>
</ul>
</body>
</html>
{{end}}
new.html
{{define "new"}}
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<title>新規登録</title>
</head>
<body>
<form action="/user/new" method="POST">
user_id:<input type="text" name="userID">
<br>
name: <input type="text" name="name">
<br>
<input type="submit" value="登録">
</form>
</body>
</html>
{{end}}