LoginSignup
1
1

More than 5 years have passed since last update.

フレームワーク「GIN」を使ってみた(CRUD処理)

Posted at

とりあえず、ソースを保存。
備忘用なので、説明は後で。

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}}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1