GinでORM(xorm)を使ってみる

Gin API実装

エウレカさんのチュートリアルに沿ってやってみた

Go言語製WAF GinでWebアプリを作ってみる【準備編】 | eureka tech blog

モデル(Model)設計

modelsディレクトリにuser.goを作成する

  • Repository構造体定義
  • Repository構造体に「DBからデータを取得する処理」を定義
  • RepositoryからUser構造体を生成する処理を実装

ソースは以下のとおり

package models
 
import (
    "github.com/go-xorm/xorm"
    _ "github.com/go-sql-driver/mysql"
    "fmt"
)
 
var engine *xorm.Engine
 
 
// init ...
func init() {
    var err error
    engine, err = xorm.NewEngine("mysql", "root:pass@/golang")
    if err != nil {
        panic(err)
    }
}

// User is
type User struct {
    ID       int    `json:"id" xorm:"'id'"`
    Username string `json:"name" xorm:"'nickname'"`
}

// NewUser ...
func NewUser(id int, username string) User {
    return User{
        ID:       id,
        Username: username,
    }
}
 
// UserRepository is
type UserRepository struct {
}
 
// NewUserRepository ...
func NewUserRepository() UserRepository {
    return UserRepository{}
}
 
// GetByID ...
func (m UserRepository) GetByID(id int) *User {
    var user = User{ID: id}
    has, hage := engine.Get(&user)
    if has {
        return &user
    }
 
    return nil
}

xormとは

Go言語のORM ドキュメント

Documentation - xorm: Simple & Powerful ORM Framework for Go Programming Language

1.インストール

$ go get github.com/go-xorm/xorm

2.まずデータベースのためのEngineを作る

engine, err := xorm.NewEngine(driverName, dataSourceName)

user.goのソース上では

engine, err = xorm.NewEngine("mysql", "root:pass@/golang")

driveNameにDB、dataSourceNameにユーザ名:パスワード/ DB名をそれぞれ指定する。

3.ORM Methods(基本)

  • Insert
affected, err := engine.Insert(&struct)
//INSERT INTO struct () values ()
  • 1レコード参照
has, err := engine.Get(&user)
//SELECT * FROM user LIMIT 1
  • 複数レコード参照
sliceOfStructs := new(Struct)
err := engine.Find(sliceOfStructs)
// SELECT * FROM user
  • update文
affected, err := engine.Id(...).Update(&user)
// UPDATE user SET ...
  • delete文
affected, err := engine.Where(...).Delete(&user)
// DELETE FROM user Where ...
  • レコードcount
counts, err := engine.Count(&user)
// SELECT count(*) AS total FROM user

他にも複数条件や並び替えなどの指定は以下ドキュメントを参照する github.com/go-xorm/xorm - Go Walker

*Xormはまた、生のSQL実行をサポートしています

results, err := engine.Query("select * from user")

mysqlのドライバーもinstall忘れずに

$ go get github.com/go-sql-driver/mysql

次に

xorm:”‘カラム名'”とアノテーションを入れることで、構造体のフィールドとデータベースのカラムをマッピング

type User struct {
    ID       int    `json:"id" xorm:"'id'"`
    Username string `json:"name" xorm:"'nickname'"`
}

Controller実装

modelのNewUserRepositoryからGetByIDの中身を取得して返すcontrollerを作成

package controllers
 
import (
    "golang/models"
)
 
// User
type User struct {
}
 
// NewUser
func NewUser() User {
    return User{}
}
 
// Get 
func (c User) Get(n int) interface{} {
    repo := models.NewUserRepository()
    user := repo.GetByID(n)
    return user
}

main.go実装

main.goにuser_idユーザー情報を返します。

package main
 
import (
    "golang/controllers"
    "github.com/gin-gonic/gin"
    "reflect"
    "strconv"
)
 
// main ...
func main() {
    router := gin.Default()
    router.GET("/:id", func(c *gin.Context) {
        // Pramを処理する
        n := c.Param("id")
        id, err := strconv.Atoi(n)
        if err != nil {
            c.JSON(400, err)
            return
        }
        if id <= 0 {
            c.JSON(400, gin.H{"status": "id should be bigger than 0"})
            return
        }
        // データを処理する
        ctrl := controllers.NewUser()
        result := ctrl.Get(id)
        if result == nil || reflect.ValueOf(result).IsNil() {
            c.JSON(404, gin.H{})
            return
        }

        c.JSON(200, result)
    })
    router.Run(":8080")
}

ここまででhttp://localhost8080/:idを指定すると DBに入っている情報を参照してデータを返してくれることが分かりました。

ここまではチュートリアルなので次回はviewなどを作り簡易なサイトを作成できればと思います。

github.com