前書
2020年8月、GORMのv2.0がリリースされました。
変更点が多くて、一部の関数でv1と互換性がないため、この記事で取り上げてみたいと思います。
change log link
Change Log
v2.0 - 2020.08
GORM 2.0はゼロから書き直されたもので、互換性のないAPIの変更と多くの改善が導入されています
- パフォーマンスの改善
- モジュール性の向上
- Context, Batch Insert, Prepared Statment Mode, DryRun Mode, Join Preload, Find To Map, Create From Map, FindInBatches サポートします。
- SavePoint/RollbackTo/Nested Transaction サポートします。
- 名前付き引数、グループ条件、アップサート、ロック、オプティマイザー/インデックス/コメントヒントのサポート、サブクエリの改善
- 完全な自己参照関係のサポート、結合テーブルの改善、バッチデータの関連付けモード
- 作成/更新時間を追跡するための複数のフィールドのサポート。UNIX(ミリ/ナノ)秒のサポートが追加されます。
- フィールド権限のサポート: read-only, write-only, create-only, update-only, ignored
- 新しいプラグインシステム:複数のデータベース、プラグインDatabase Resolverによる読み取り/書き込み分割のサポート、プロメテウスの統合…
- 新しいフックAPI:プラグインとの統合インターフェース
- 新しい移行:関係、制約/チェッカーのサポート、拡張インデックスのサポートのためのデータベース外部キーを作成できます
- 新しいロガー:コンテキストサポート、拡張性の向上
- 統一された命名ルール:table name, field name, join table name, foreign key, checker, index name
- より適切のカスタマイズされたデータ型のサポート (e.g: JSON)
以下にバージョン差異による非互換箇所を記載します。
データベース接続
v2
main.go
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main(){
dsn := "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local"
v2_db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}
v1
main.go
package main
import (
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
)
func main(){
v1_db, err := gorm.Open("mysql", "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local")
}
データベースを閉じる
v2
main.go
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main(){
dsn := "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local"
v2_db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
db, err := v2_db.DB()
defer db.Close()
}
v1
main.go
package main
import (
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
)
func main(){
v1_db, err := gorm.Open("mysql", "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local")
defer v1_db.Close()
}
新規テーブル
v2
main.go
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
Id int
Name string
Age int
Addr string
Pic string
}
func main(){
dsn := "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local"
v2_db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
// Usersというテーブルを作ります
v2_db.Migrator().CreateTable(&User{})
}
v1
main.go
package main
import (
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
)
func main(){
v1_db, err := gorm.Open("mysql", "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local")
// Usersというテーブルを作ります
v1_db.CreateTable(&User{})
}
テーブル削除
v2
main.go
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
Id int
Name string
Age int
Addr string
Pic string
}
func main(){
dsn := "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local"
v2_db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
// テーブルの削除
v2_db.Migrator().DropTable(&User{})
}
###v1
main.go
package main
import (
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
)
func main(){
v1_db, err := gorm.Open("mysql", "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local")
// テーブルの削除
v1_db.DropTable("users")
}
テーブル存在の確認
v2
main.go
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main(){
dsn := "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local"
v2_db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
// テーブルの存在確認
b := v2_db.Migrator().HasTable("users")
// 戻り値はboolタイプである
fmt.Println(b)
}
v1
main.go
package main
import (
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
)
func main(){
v1_db, err := gorm.Open("mysql", "root:@tcp(localhost:3306)/gorm_project?charset=utf8&parseTime=True&loc=Local")
// テーブルの存在確認
v1_db.HasTable("users")
// 戻り値はboolタイプである
fmt.Println(b)
}
Related関数の廃棄
v2ではRelated関数の使用はできません。
// Related get related associations
func (s *DB) Related(value interface{}, foreignKeys ...string) *DB {
return s.NewScope(s.Value).related(value, foreignKeys...).db
}
LogModeの使い方の変更
v2
// LogLevelの指定
db.Logger.LogMode(4)
v1
db.LogMode(真偽値)