1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GORMのPreloading (Eager loading)を使って2つのテーブルから値を取得する

Posted at

自己紹介

現在都内の企業でWebエンジニアのインターン生としてお世話になっている大学2年生です!
インターンや個人開発で学んだことや苦労したことを記事にしています!
よろしくお願いします🙇🏻‍♂️

はじめに

インターンで2つのテーブルから値を取得するのに苦労したので、備忘録として記事に残しておきます!

環境

  • OS:M1MacOS ver12.0.1
  • DB:Mysql ver8.0.27
  • SQLマイグレーションツール:sql-migrate
  • フレームワーク:Echo
  • ORM:GORM

Pleloading (Eager loading)とは

Preloadingとは事前読み込みのことです。
多くのORMで実装されている機能であり、GORMでもPreload(モデル名)を指定することで、リソースを先読みしてキャッシュできるようなる。

参考

公式サイトにはこう書いてあります。

GORMの Preload を使用すると、別のSQLを発行して関連レコードを eager loading することができます。

参考
GORM公式サイト

構造体の定義

GOの構造体は親テーブルにforeignKey:XXXXXで外部キーを設定します。
今回はUser_status_idを外部キーとして設定するのでforeignKey:User_status_idと記述します。
下記のように記述することでusersテーブルのidとuser_statuesテーブルのuser_status_idが一致するデータを取得できます。
親テーブルはデフォルトでidが参照されるようになっています。

user.go
type User struct {
	Id              int         `gorm:"primaryKey" json:"id"`
	First_name      string      `json:"first_name"`
	Family_name     string      `json:"family_name"`
	User_status_txt string      `json:"user_status_txt"`
	User_status     User_status `gorm:"foreignKey:User_status_id" json:"user_status"`
}

type User_status struct {
	Id             int        `gorm:"primaryKey" json:"id"`
	Status_name     string     `json:"status_name"`
	User_status_id int        `json:"user_status_id"`
}

親テーブルの参照されるデータをidから変更したい場合は
AssociationForeignKeyを使うことで変更することができます。
下記は、User_status_id Status_name AssociationForeignKeyUser_status_txt を入れています。

user.go
type User struct {
	Id              int         `gorm:"primaryKey" json:"id"`
	First_name      string      `json:"first_name"`
	Family_name     string      `json:"family_name"`
	User_status_txt string      `json:"user_status_txt"`
	User_status     User_status `gorm:"foreignKey:Status_name;AssociationForeignKey:User_status_txt" json:"user_status"`
}

type User_status struct {
	Id             int        `gorm:"primaryKey" json:"id"`
	Status_name     string     `json:"status_name"`
	User_status_id int        `json:"user_status_id"`
}

値の取得

実際にPreloadを使い、値を取得してみます。
下記のように記述することでpreloadを使い2つのテーブルから値を取得する事ができます。

func UserShow() echo.HandlerFunc {
	return func(c echo.Context) error {
		db := dbconnect.Connect()
		defer db.Close()	
		user := model.User{}
		user_id := c.Param("id")
		result := db.Preload("User_status").Find(&user, "id = ?", user_id)
		if result.RecordNotFound() {
			fmt.Println("レコードが見つかりません")
		}
		return c.JSON(http.StatusOK, user)
	}
}

取得できるデータ

{
    "id": 1,
    "first_name": "優介",
    "family_name": "飯嶋",
	"user_status_txt":"一般人",
    "user_status": {
        "id": 2,
        "status_name": "男性",
        "user_status_id": 1,
    } 
}

iduser_status_id が一致しているデータが取れています。

また、User_status_id Status_name
AssociationForeignKeyUser_status_txt を入れた場合。

{
    "id": 2,
    "first_name": "鈴木",
    "family_name": "太郎",
    "user_status_txt": "通行人A",
    "user_status": {
        "id": 3,
        "status_name": "通行人A",
        "user_status_id": 3,      
    }
}

Status_nameUser_status_txt が一致しているデータが取れています。

終わりに

この記事が誰かの役に立てれば幸いです!

間違っている箇所もあるとは思いますが、教えてくださると助かります。

ではいい一日を👍

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?