以前gin gormでテーブル操作で一連のテーブル操作をやってみた
しかし、どうもBDのコネクションは保持したままの方が良いようなので、修正してみる
ついでにこちらと同じGo Modules管理に変更している
以下雑にコードをのせているだけなので、何が変わったかは↑の記事と見比べてください(すまん
docker-compose.yml
docker-compose.yml
services:
app:
container_name: gin_app
image: golang:1.12.0-alpine
volumes:
- .:/go/src/app
command: >
sh -c "cd /go/src/app &&
apk update &&
apk add --no-cache git &&
GO111MODULE=off go get -u github.com/codegangsta/gin &&
go mod init || : &&
gin -i run"
ports:
- 3001:3001
environment:
GO111MODULE: "on"
DB
db/db.go
package db
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
var database *gorm.DB
func Connection() *gorm.DB {
var err error
database, err = gorm.Open("mysql", "root:@tcp(db:3306)/gin_app?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic("failed to connect database")
}
database.LogMode(true)
return database
}
func DB() *gorm.DB {
return database
}
毎回接続せずにコネクションを変数に保持する形式に変更。他packageでは db.DB()
で取得できるようにしている
マイグレーション
こちらもメソッドに。任意で実行できるように変更
migrate/migrate.go
package main
import (
"app/db"
"app/model"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
func main() {
db.Connection()
defer db.DB().Close()
db.DB().AutoMigrate(&model.User{})
db.DB().AutoMigrate(&model.UserName{})
}
マイグレーション実行
Go Modules管理に変更したら以前の方法だとエラーになるので少し修正
$ docker exec -it gin_app sh -c "cd /go/src/app; go run migrate/migrate.go"
モデル
ここは変更なし
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
}
コントローラ
DBの取得方法を変更
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.DB()
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.DB()
var users []model.User
result := db.Preload("UserName").Find(&users)
c.JSON(200, result.Value)
}
func (t *User) Create(c *gin.Context) {
db := db.DB()
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.DB()
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.DB()
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
はじめにDB接続をするように変更
main.go
package main
import (
"app/controller"
"github.com/gin-gonic/gin"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
func main() {
db.Connection()
defer db.DB().Close()
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
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()
}