9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

gin gormでテーブル操作

Last updated at Posted at 2019-04-14

2020/6/30 改良しました

前回DB接続まで
今回も雑にテーブルの基本操作

DB接続

接続をメソッドに。本来は環境やDBを設定ファイルなどで切り替えれるようにするのが良いか

db/db.go
package db

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

func Connection() *gorm.DB {
	db, err := gorm.Open("mysql", "root:@tcp(db:3306)/gin_app?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	db.LogMode(true)
	return db
}

マイグレーション

こちらもメソッドに。任意で実行できるように変更

migrate/migrate.go
package main

import (
	"app/db"
	"app/model"

	_ "github.com/jinzhu/gorm/dialects/mysql"
)

func main() {
	db := db.Connection()
	defer db.Close()

	db.AutoMigrate(&model.User{})
	db.AutoMigrate(&model.UserName{})
}

マイグレーション実行は

docker exec -it gin_app go run /go/src/app/migrate/migrate.go

モデル

各テーブルをモデルとして定義
今回はリレーションも使って見たかったので user user_name を作成

テーブルは↓こんなかんじ

$ docker exec -it gin_db mysql -u root -e "use gin_app; show tables;"
+-------------------+
| Tables_in_gin_app |
+-------------------+
| user_names        |
| users             |
+-------------------+
model/user.go
package model

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type User struct {
	gorm.Model
	UserName UserName
}
model/user_name.go
package model

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type UserName struct {
	gorm.Model
	UserID uint
	Name   string
}

コントローラ

名前はserviceでもなんでもいいかもしれない
とりあえず動けばいいのでバリデーションなどは入れていません

controller/user.go
package controller

import (
	"app/db"
	"app/model"

	"github.com/gin-gonic/gin"
)

type User struct{}

func NewUser() *User {
	return &User{}
}

func (t *User) Get(c *gin.Context) {
	db := db.Connection()
	defer db.Close()

	var user model.User
	result := db.First(&user, c.Param("id")).Related(&user.UserName)
	c.JSON(200, result.Value)
}

func (t *User) List(c *gin.Context) {
	db := db.Connection()
	defer db.Close()

	var users []model.User
	result := db.Preload("UserName").Find(&users)
	c.JSON(200, result.Value)
}

func (t *User) Create(c *gin.Context) {
	db := db.Connection()
	defer db.Close()

	var user model.User
	db.Create(&user)

	var userName model.UserName
	c.BindJSON(&userName)
	userName.UserID = user.ID
	db.Create(&userName)
}

func (t *User) Update(c *gin.Context) {
	db := db.Connection()
	defer db.Close()

	var user model.User
	db.First(&user, c.Param("id")).Related(&user.UserName)
	if user.UserName.ID > 0 {
		c.BindJSON(&user.UserName)
		db.Save(&user.UserName)
	}
}

func (t *User) Delete(c *gin.Context) {
	db := db.Connection()
	defer db.Close()

	var user model.User
	db.First(&user, c.Param("id")).Related(&user.UserName)
	if user.ID > 0 {
		db.Delete(&user)
	}
	if user.UserName.ID > 0 {
		db.Delete(&user.UserName)
	}

	// こっちの消し方でも良い
	// db.Where("id = ?", c.Param("id")).Delete(&model.User{})
	// db.Where("user_id = ?", c.Param("id")).Delete(&model.UserName{})
}

main

各操作をルーターに追加

main.go
package main

import (
	"app/controller"

	"github.com/gin-gonic/gin"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

func main() {
	r := gin.Default()
	r.GET("/users", controller.NewUser().List)
	r.GET("/users/:id", controller.NewUser().Get)
	r.POST("/users", controller.NewUser().Create)
	r.PUT("/users/:id", controller.NewUser().Update)
	r.DELETE("/users/:id", controller.NewUser().Delete)

	r.Run()
}

実行

作成

curl -X POST http://localhost:3001/users -d '{"name": "hoge"}'

1件取得

curl http://localhost:3001/users/1

全件取得

curl http://localhost:3001/users/

更新

curl -X PUT http://localhost:3001/users/1 -d '{"name": "huga"}'

削除

curl -X DELETE http://localhost:3001/users/1

おわり

9
7
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
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?