GORMは、Goの構造体をデータベーステーブルにマッピングすることで、データベースの相互作用を簡素化します。 GOMRの機能をフルに活用するために、基本となるモデルの宣言方法を理解しましょう。
モデルを宣言する
モデルは通常の構造体を使用して定義されます。 これらの構造体には、database/sql
パッケージのScannerインタフェースとValuerインタフェースを実装している限り、基本的なGoの型、それらのポインタまたはエイリアス、あるいはカスタムタイプを含むフィールドを含めることができます。
User
モデルの次の例を考えてみましょう。
type User struct { |
このモデルは次のように扱われます。
uint
,string
, およびuint8
のような基本的なデータ型がそのまま使用されます。*string
や*time.Time
のような型へのポインタは、null許容型のフィールドを示します。database/sql
パッケージのsql.NullString
とsql.NullTime
を使用することで、null許容フィールドを細かく制御できます。CreatedAt
とUpdatedAt
は特別なフィールドとして扱われ、レコードが作成または更新されたとき、GORMが自動的に現在の時刻をセットします。- エクスポートされていないフィールド(先頭が小文字)はマップされません
GORMにおけるモデル宣言の基本的な機能に加えて、シリアライザタグによるシリアライズのサポートに注目することが重要です。 この機能により、特にカスタム・シリアライズ・ロジックを必要とするフィールドについて、データの格納方法とデータベースからの取得方法の柔軟性が高まります。詳細な説明については シリアライザー を参照してください。
規約
主キー: GORMは各モデルのデフォルト主キーとして
ID
という名前のフィールドを使用します。テーブル名: デフォルトでは、GORMは構造体名を
スネークケース
に変換し、テーブル名を複数形にします。 たとえば、User
構造体はデータベース内ではusers
になり、GormUserName
はgorm_user_names
になります。カラム名: GORMは、データベース内のカラム名を自動的に
スネークケース
に変換します。タイムスタンプフィールド: GORMは
Created
およびUpdatedAt
という名前のフィールドを使用して、レコードの作成と更新時間を自動的に追跡します。
次の規約に従うことで、コンフィグやコードを書く量を大幅に減らすことができます。 もちろん、GORMには柔軟性があるため、標準の規約が要件に沿わない場合はこれらの設定をカスタマイズすることもできます。 規約のカスタマイズについては、GORMドキュメントの 規約を参照してください。
gorm.Model
GORMで使用できる定義済み構造体 gorm.Model
には、一般的に使用される以下のフィールドが含まれます。
// gorm.Modelの定義 |
構造体への埋め込み: あなたが作成した構造体に
gorm.Model
を直接埋め込むことで、これらのフィールドを自動的に含めることができます。 これは、異なる複数のモデル間で一貫性を維持し、GORMの組み込み規則を活用する場合に便利です。参照: 構造体の埋め込みフィールド:
ID
: 各レコードの一意の識別子(主キー)。CreatedAt
: レコードの作成時に自動的に現在時刻がセットされます。UpdatedAt
: レコードが更新されるたびに、自動的に現在の時刻に更新されます。DeletedAt
: 論理削除(実際にはデータベースからレコードを削除せず、削除済みとしてマークする)に使用されます。
高度な機能
フィールドレベルの権限
エクスポートされたフィールドはGORMでCRUDを実行するための権限をすべて持ちます。フィールド単位で権限を変更したいときはタグを使用することにより、特定のフィールドを読み取り専用、書き込み専用、作成専用、更新専用、あるいは無視にすることができます。
注意 GORM Migrator を使用してテーブルを作成した場合、除外設定されたフィールドは作成されません
type User struct { |
作成・更新日時のトラッキング/Unix (ミリ・ナノ) 秒でのトラッキング
GORMの規約では、作成/更新時間をトラッキングするのに CreatedAt
, UpdatedAt
を使用します。それらのフィールドがモデルに定義されている場合、作成/更新時間に現在時刻を値としてセットします。
別の名前のフィールドを使用する場合、 autoCreateTime
、 autoUpdateTime
タグを使用することで設定を変更することができます。
time.Timeの代わりにUNIX (ミリ/ナノ) 秒を保存したい場合、フィールドのデータ型を time.Time
から int
に変更するだけで保存が可能になります。
type User struct { |
構造体の埋め込み
匿名(anonymous field)フィールドでモデルの定義がなされている場合、埋め込まれた構造体のフィールドは親の構造体のフィールドとして含まれることになります。例:
type Author struct { |
通常のフィールドで構造体の定義がなされている場合、 embedded
タグを使用して構造体の埋め込みを行うことができます。例:
type Author struct { |
また、 embeddedPrefix
タグを使用することで、埋め込まれた構造体のフィールド名にプレフィックスを追加することができます。例:
type Blog struct { |
タグはモデル宣言時に任意で使用できます。GORMは以下のタグをサポートしています。大文字小文字は区別されませんが、camelCase
にすることを推奨します。 複数のタグを使用するには、セミコロン (;
)で区切ります。 パーサーにとって特別な意味を持つ文字は、バックスラッシュ (\
) でエスケープすることでパラメーターの値として使用できます。
タグ名 | 説明 |
---|---|
column | データベースのカラム名 |
type | カラムのデータ型を指定します。bool, int, uint, float, string, time, bytes などの全てのデータベースで動作する一般的なデータ型と互換性のあるものが良いでしょう。また、not null , size , autoIncrement … などの他のタグと併用することも可能です。 varbinary(8) などの特定のデータベースでのみ使用可能なデータ型もサポートしていますが、それらのデータ型を使用する場合は、データ型をフルで指定する必要があります。例: MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT |
serializer | データを直列化および並列化するためのシリアライザを指定します。例: 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 を指定します。例: autoCreateTime:nano |
autoUpdateTime | カラムの作成時/更新時に現在日時を自動でセットします。int 型のフィールドに対してはUNIX秒でセットされます。ナノ秒/ミリ秒でセットしたい場合は値に nano /milli を指定します。例: autoUpdateTime: milli |
index | インデックスを作成します。複数のフィールドで同じ名前を使用した場合は複合インデックスが作成されます。詳細はインデックスを参照してください。 |
uniqueIndex | index と同様です。ただし、一意なインデックスを作成します。 |
check | CHECK制約を作成します(例: check:age > 13 )。制約を参照のこと |
<- | フィールドの書き込み権限を設定します。<-:create : 作成のみ可能。<-:update : 更新のみ可能。<-:false : 書き込み権限なし。<- : 作成/更新権限あり。 |
-> | フィールドの読み込み権限を設定します。->:false : 読み込み権限なし。 |
- | フィールドを無視します。 - : 読み取り/書き込み権限なし。-:migration : マイグレーション権限なし。-:all : 読み取り/書き込み/マイグレーション権限なし。 |
comment | マイグレーション実行時にフィールドにコメントを追加します |
アソシエーションで使用できるタグ
GORMではアソシエーション用のタグを使用することで、外部キー、制約、many2many(多対多)テーブルなどを設定できます。詳細は Associations section を参照してください。