LoginSignup
47
46

More than 5 years have passed since last update.

Go言語でORマップ

Posted at

Go言語で OR Mapping をしたくなったら、どのライブラリを使うのが良さそうか調べてみた。

結論

現状のアクティブさと、人気度から考えて、gorp, gorm, xorm の3択

Railsからの置換えの場合

gormの1択。
xormもマッパーとかを自前で書けば、いけるかもしれない?

Goでシンプルなアプリ

structのDBのマップだけしてくれるシンプルなgorpで良さそう。

Goで大きめのアプリ

xormがセンス良さそう。ただ、
go的じゃないけど、大きめのRails的なので良さそうだったらgorm、
go的にminimalistを通すならgorpもやはり候補に入る感じ。

gorp

1498 star, 214 fork

基本概念として、StructとDBのマッピングをするだけのシンプルな機構。
複雑なアソシエーションの機構はないが、Transactionや、Before/After Hookなど必要なものは揃っている感じ。

Freatures

  • Bind struct fields to table columns via API or tag
  • Support for embedded structs
  • Support for transactions
  • Forward engineer db schema from structs (great for unit tests)
  • Pre/post insert/update/delete hooks
  • Automatically generate insert/update/delete statements for a struct
  • Automatic binding of auto increment PKs back to struct after insert
  • Delete by primary key(s)
  • Select by primary key(s)
  • Optional trace sql logging
  • Bind arbitrary SQL queries to a struct
  • Bind slice to SELECT query results without type assertions
  • Use positional or named bind parameters in custom SELECT queries
  • Optional optimistic locking using a version column (for update/deletes)

gorm

1727 star, 179 fork

RailsサーバーをGoに置き換えようという場合にすごく便利そうなOR Mapper。

以下に本家に載っているサンプルスキーマを見れば分かる通り、created_at, updated_at, Soft Delete の deleted_at などマップの仕方が、RailsのConventionに従っている。

type User struct {
    ID           int
    Birthday     time.Time
    Age          int
    Name         string  `sql:"size:255"` // Default size for string is 255, you could reset it with this tag
    Num          int     `sql:"AUTO_INCREMENT"`
    CreatedAt    time.Time
    UpdatedAt    time.Time
    DeletedAt    *time.Time

    Emails            []Email         // One-To-Many relationship (has many)
    BillingAddress    Address         // One-To-One relationship (has one)
    BillingAddressID  sql.NullInt64   // Foreign key of BillingAddress
    ShippingAddress   Address         // One-To-One relationship (has one)
    ShippingAddressID int             // Foreign key of ShippingAddress
    IgnoreMe          int `sql:"-"`   // Ignore this field
    Languages         []Language `gorm:"many2many:user_languages;"` // Many-To-Many relationship, 'user_languages' is join table
}

type Email struct {
    ID      int
    UserID  int     `sql:"index"` // Foreign key (belongs to), tag `index` will create index for this field when using AutoMigrate
    Email   string  `sql:"type:varchar(100);unique_index"` // Set field's sql type, tag `unique_index` will create unique index
    Subscribed bool
}

type Address struct {
    ID       int
    Address1 string         `sql:"not null;unique"` // Set field as not nullable and unique
    Address2 string         `sql:"type:varchar(100);unique"`
    Post     sql.NullString `sql:"not null"`
}

type Language struct {
    ID   int
    Name string `sql:"index:idx_name_code"` // Create index with name, and will create combined index if find other fields defined same name
    Code string `sql:"index:idx_name_code"` // `unique_index` also works
}

他にも、ScopeやCallback、関数もPluck等が存在し、基本的にRailsのActiveRecordをモデルに作られているようなライブラリ。

xorm

662 star, 131 fork

まだまだ、他のものと比べ人気は少ないが、
http://xorm.io/docs
と割ときちっとしたドキュメントがあり、イケている感がある。

Go的でスマート。Mapperがsnake_caseにするだけか、完全に同一にするだけのみ用意されているので、Railsには合わない。
その分、has_many的なアソシエーションのサポートが無かったり、Go的な本当に必要な物だけ作る思想がある気がする。

Features

  • Struct <-> Table Mapping Support
  • Chainable APIs
  • Transaction Support
  • Both ORM and raw SQL operation Support
  • Sync database schema Support
  • Query Cache speed up
  • Database Reverse support, See Xorm Tool README
  • Simple cascade loading support
  • Optimistic Locking support

という感じで、特にDBからスキーマを作ってくれる機構があるのがすごい。

Tips: SQL Injection を防ぐ機構

Go言語では、全体として、SQL Injectionを防ぐのは言語で提供するというより、各DBのプレースホルダの機構を使って対応しようという方針らしい。

Postgres:
db.Query("select name, phone from contacts where state = $1 and totalSales > $2", "WA", 1000000)

Some other databases:
db.Query("select name, phone from contacts where state = ? and totalSales > ?", "WA", 1000000)

参考

47
46
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
47
46