課題

golangのデフォルトコネクタdatabase/sqlだと生クエリを叩くことになるので、SQLインジェクション対策をしたいなと思っていたが、SQLインジェクション対策を0から実装するのは面倒なので、ORマッパーのプラグインを導入

gormって?

  • RailsやLaravelっぽいORマッピングを実装してくれる
  • Modelとなるstructに対し、gorm.ModelsというパラメータをつけるだけでID, updated_at, created_at, deleted_at等をつけてくれる
  • リレーションもstructの中に定義しておけば勝手にやってくれる
  • structを元にマイグレーションをやってくれる
  • 使い方はdatabase/sqlに近い

実装方法

コネクション作成周りはdatabase/sqlと同じでいけます

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)
...
toml.DecodeFile("config.toml", &config)
dbconf := config.Mysql.User + ":" + config.Mysql.Pass + "@tcp(" + config.Mysql.Host+ ":3306)/" + config.Mysql.DB
db, err = gorm.Open("mysql", dbconf)
if err != nil {
	panic(err.Error())
}
defer db.Close() // 関数がリターンする直前に呼び出される

リレーションに関しても

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
type User struct {
	gorm.Model
	Api Api `json:"api" gorm:"ForeignKey:UserId"` // Has one
}
type Api struct {
	gorm.Model
	UserId int
	ApiId int `json:"api_id"` // Belongs To
	AccessToken string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
}

とかしておけば、勝手に解決してくれます。 jsonの受け皿としても使えるので、リクエストのbodyに対して、自動割当も可能です。

1
2
3
4
5
6
7
8
func register(w http.ResponseWriter, r *http.Request) {
	docoder := json.NewDecoder(r.Body)
	var user User
	err := docoder.Decode(&user)
	if err != nil {
		panic(err)
	}
}

更に、マイグレーションに関しても

1
	db.AutoMigrate(&User{}, &Api{})

とやるだけ。