GORM バージョン2の変更点

# 前書

2020年8月、GORMのv2.0がリリースされました。
変更点が多くて、一部の関数でv1と互換性がないため、この記事で取り上げてみたいと思います。
[change log link](https://gorm.io/docs/changelog.html)


```
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

```go: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

```go: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

```go: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

```go: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

```go: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

```go: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

```go: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

```go: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

```go: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

```go: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(真偽値)
```