GORMは、Goの構造体をデータベースのテーブルにマッピングすることで、データベースとのやり取りを簡素化します。GORMでモデルを宣言する方法を理解することは、その全機能を活用するための基礎となります。
モデルの宣言
モデルは通常の構造体を使用して定義されます。これらの構造体には、Goの基本型、ポインタまたはこれらの型のエイリアス、あるいはカスタム型でさえ、`database/sql`パッケージのScannerインターフェースとValuerインターフェースを実装している限り、フィールドを含めることができます。
`User`モデルの次の例を考えてみましょう。
type User struct { |
このモデルでは、
- `uint`、`string`、`uint8`のような基本データ型が直接使用されています。
- `*string`や`*time.Time`のような型へのポインタは、NULL許容フィールドを示します。
- `database/sql`パッケージの`sql.NullString`と`sql.NullTime`は、より詳細な制御を必要とするNULL許容フィールドに使用されます。
- `CreatedAt`と`UpdatedAt`は、レコードが作成または更新されたときにGORMが自動的に現在の時刻を設定する特別なフィールドです。
GORMにおけるモデル宣言の基本機能に加えて、serializerタグによるシリアライズのサポートが重要です。この機能は、データベースにデータを格納および取得する方法の柔軟性を高めます。特に、カスタムシリアライズロジックが必要なフィールドに有効です。詳細な説明については、Serializerを参照してください。
規約
**主キー**: GORMは、各モデルのデフォルトの主キーとして`ID`という名前のフィールドを使用します。
**テーブル名**: デフォルトでは、GORMは構造体名を`snake_case`に変換し、テーブル名として複数形にします。たとえば、`User`構造体はデータベースでは`users`になります。
**カラム名**: GORMは、データベースのカラム名として構造体フィールド名を自動的に`snake_case`に変換します。
**タイムスタンプフィールド**: GORMは、`CreatedAt`と`UpdatedAt`という名前のフィールドを使用して、レコードの作成時刻と更新時刻を自動的に追跡します。
これらの規約に従うことで、記述する必要がある設定やコードの量を大幅に削減できます。ただし、GORMは柔軟性があり、デフォルトの規約が要件に合わない場合は、これらの設定をカスタマイズすることもできます。GORMの規約に関するドキュメントで、これらの規約のカスタマイズについて詳しく学ぶことができます。
`gorm.Model`
GORMは、一般的に使用されるフィールドを含む定義済み構造体`gorm.Model`を提供します。
// gorm.Model definition |
**構造体への埋め込み**: これらのフィールドを自動的に含めるには、`gorm.Model`を構造体に直接埋め込むことができます。これは、異なるモデル間で一貫性を維持し、GORMの組み込み規約を活用するのに役立ちます。埋め込み構造体を参照してください。
含まれるフィールド:
- `ID`: 各レコードの一意の識別子(主キー)。
- `CreatedAt`: レコードが作成されたときに現在の時刻に自動的に設定されます。
- `UpdatedAt`: レコードが更新されるたびに現在の時刻に自動的に更新されます。
- `DeletedAt`: 論理削除(レコードをデータベースから実際に削除することなく、削除済みとしてマークする)に使用されます。
高度な設定
フィールドレベルのパーミッション
エクスポートされたフィールドは、GORMでCRUDを実行する際にすべてのパーミッションを持ちます。GORMでは、タグを使用してフィールドレベルのパーミッションを変更できるため、フィールドを読み取り専用、書き込み専用、作成専用、更新専用、または無視するように設定できます。
**注意** 無視されたフィールドは、GORM Migratorを使用してテーブルを作成する際に作成されません。
type User struct { |
作成/更新時刻/Unix(ミリ/ナノ)秒の追跡
GORMは、慣例により`CreatedAt`、`UpdatedAt`を使用して作成/更新時刻を追跡します。GORMは、フィールドが定義されている場合、作成/更新時に現在の時刻を設定します。
異なる名前のフィールドを使用するには、`autoCreateTime`、`autoUpdateTime`タグでこれらのフィールドを設定できます。
時刻の代わりにUNIX(ミリ/ナノ)秒を保存する場合は、フィールドのデータ型を`time.Time`から`int`に変更するだけです。
type User struct { |
埋め込み構造体
匿名フィールドの場合、GORMはそのフィールドを親構造体に含めます。例:
type User struct { |
通常の構造体フィールドの場合は、`embedded`タグを使用して埋め込むことができます。例:
type Author struct { |
また、`embeddedPrefix`タグを使用して、埋め込みフィールドのDB名にプレフィックスを追加することもできます。例:
type Blog struct { |
タグはモデルを宣言する際にオプションで使用できます。GORMは次のタグをサポートしています。
タグは大文字と小文字を区別しませんが、`camelCase`が推奨されます。
タグ名 | 説明 |
---|---|
column | カラムのDB名 |
type | カラムのデータ型。すべてのデータベースで動作し、`not null`、`size`、`autoIncrement`…のような他のタグと一緒に使用できる、bool、int、uint、float、string、time、bytesなどの互換性のある汎用型を使用することが推奨されます。 `varbinary(8)`のような特定のデータベースデータ型もサポートされています。特定のデータベースデータ型を使用する場合は、`MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT`のように、完全なデータベースデータ型である必要があります。 |
serializer | データをDBにシリアライズおよびデシリアライズする方法のシリアライザを指定します。例:`serializer:json/gob/unixtime` |
size | カラムデータのサイズ/長さを指定します。例:`size:256` |
primaryKey | カラムを主キーとして指定します。 |
unique | カラムを一意として指定します。 |
default | カラムのデフォルト値を指定します。 |
precision | カラムの精度を指定します。 |
scale | カラムのスケールを指定します。 |
not null | カラムをNOT NULLとして指定します。 |
autoIncrement | カラムを自動増分として指定します。 |
autoIncrementIncrement | 自動増分ステップ。連続する列の値の間隔を制御します。 |
embedded | フィールドを埋め込みます。 |
embeddedPrefix | 埋め込みフィールドのカラム名プレフィックス。 |
autoCreateTime | 作成時の現在の時刻を追跡します。`int`フィールドの場合、Unix秒を追跡します。`nano` / `milli`値を使用してUnixナノ/ミリ秒を追跡します。例:`autoCreateTime:nano` |
autoUpdateTime | 作成/更新時の現在の時刻を追跡します。`int`フィールドの場合、Unix秒を追跡します。`nano` / `milli`値を使用してUnixナノ/ミリ秒を追跡します。例:`autoUpdateTime:milli` |
index | オプション付きでインデックスを作成します。複数のフィールドに同じ名前を使用すると、複合インデックスが作成されます。詳細はインデックスを参照してください。 |
uniqueIndex | `index`と同じですが、一意のインデックスを作成します。 |
check | チェック制約を作成します。例:`check:age > 13`、制約を参照してください。 |
<- | フィールドの書き込みパーミッションを設定します。`<-:create`は作成専用フィールド、`<-:update`は更新専用フィールド、`<-:false`は書き込みパーミッションなし、`<-`は作成および更新パーミッションです。 |
-> | フィールドの読み取りパーミッションを設定します。`->:false`は読み取りパーミッションなしです。 |
- | このフィールドを無視します。`-`は読み取り/書き込みパーミッションなし、`-:migration`は移行パーミッションなし、`-:all`は読み取り/書き込み/移行パーミッションなしです。 |
comment | 移行時にフィールドにコメントを追加します。 |
アソシエーションタグ
GORMでは、アソシエーションの外部キー、制約、多対多テーブルをタグで設定できます。詳細はアソシエーションセクションを参照してください。