goのO/Rマッパー、GORM。
構造体とDB間で、いい感じにデータを変換してくれます。
普通のコードを普通に書いていても、普通に実行してくれるので、最高です!
GORMがテーブル、カラムをマッピングする仕組み
公式ドキュメントによると、
GORMは構造体名をテーブル名としてsnake_casesのように複数形にします。構造体 User の場合、対応するテーブル名は規約により users となります。
規約に従い、データベースのカラム名はフィールド名のsnake_caseを使用します。
テーブル名もカラム名も基本スネークケースで自動的に変換されるとのことです。
例えば、
type User struct {
ID uint
FirstName string
LastName string
}
のような構造体の場合
-------------------------------
| id | first_name | last_name |
-------------------------------
のテーブルと自動的にマッピングしてくれます。
構造体の変数名に数字を付けると
例えば、実例は存在するか不明ですが、2つのFirstNameを持つことになったので、末尾に数字を付けて区別するとします。
type User struct {
ID uint
FirstName2023 string
FirstName2024 string
LastName string
}
この場合
------------------------------------------------------
| id | first_name_2023 | first_name_2024 | last_name |
------------------------------------------------------
のテーブルと自動的にマッピングされそうですが、実際は
-
FirstName2023
とfirst_name_2023
-
FirstName2024
とfitst_name_2024
は自動マッピングされません。そして困るのはエラーにもならないので、原因不明のまま時間ばかり過ぎてしまうことになります・・・
解決策
はちゃんと用意されています。
column タグか NamingStrategy を利用することでカラム名を上書きできます。
出典元:GORM 規約
今回の例でいうと
type User struct {
ID uint
FirstName2023 string `gorm:"column:first_name_2023"
FirstName2024 string `gorm:"column:first_name_2024"
LastName string
}
と構造体のフィールドにcolumn
タグを付けることで、目的のテーブルとちゃんとマッピングできるようになります。
番外編
構造体名とテーブルがうまくマッピングされない場合もちゃんと解決策が用意されています。
func (User) TableName() string {
return "custom_table_names"
のようにテーブル名を返すメソッドを用意し、目的に合ったテーブル名を返すことで実現できます。
公式ドキュメントは正義
公式ドキュメントに使用方法が記載されているので、隅々から読んでいたら困ることはないでしょう。
実際ライブラリを使う時に、必要なところだけ読んで雰囲気で使う癖がありました。イレビュラーなケースに遭遇して初めてその問題解決方法を調べるわけです。Google検索でサクッと解決できる場合もあれば、時間をかけてやっと公式ドキュメントにたどり着くこともあります。
もちろん、それぞれメリット・デメリットがあるので正解はありません。公式ドキュメントを一度熟読していると知識はもちろんのこと見方まで変わりそうなので、一度試してみたいですね。