LoginSignup
2
0

More than 1 year has passed since last update.

Golang + Gorm + EchoでPreloadを使う

Last updated at Posted at 2021-11-22

はじめに

GormのPreloadに関しての備忘録です。よかったら参考にどうぞ🦍

参考のコードの詳細はこちらをご確認ください。

Preloading (Eager Loading)

公式より

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

構造体

User構造体は複数のProduct構造体を持ち、Product構造体は複数のProductImages構造体を持ちます。

type User struct {
    Id             string    `gorm:"primaryKey" json:"id"`
    Name           string    `json:"name"`
    Product        []Product `gorm:"foreignKey:UserId" json:"products"`
}

type Product struct {
    Id                  string          `gorm:"primaryKey" json:"id"`
    UserId              string          `json:"user_id"`
    Name                string          `json:"name"`
    ProductImages       []ProductImages `gorm:"foreignKey:ProductId" json:"product_images"`
}

type ProductImages struct {
    Id         string    `gorm:"primaryKey" json:"id"`
    ProductId  string    `json:"products_id"`
    Url        string    `json:"url"`
}

foreignKeyにProductが持つUserIdを付与します。
Preloadで取得したい構造体が複数の場合は構造体名の前にスライスを付与します。
→[]構造体名

Product        []Product `gorm:"foreignKey:UserId" json:"products"`

Echo実装

今回はEchoを使用し実装をしてます。説明は割愛しますので詳しくは以前書いた記事をご覧ください。

Preload実装

第一段階

Userが持つProductを全て取得する。
Preload("構造体名")をテーブル名の前に設定する。

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

取得できるデータ

{
    "id": "user",
    "name": "test",
    "products": [
        {
            "id": "01FN3Z67338ABXWMWFKEPWTBT3",
            "user_id": "user",
            "name": "test",
            "product_images": []
        },
        {
            "id": "01FN3Z683VPVWP200E4GTS73SZ",
            "user_id": "user",
            "name": "test",
            "product_images": []
        }
    ]
}

第二段階

Productが持つProductImagesを取得する。
Preload("構造体名.子構造体")をテーブル名の前に設定する。

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

取得できるデータ

{
    "id": "user",
    "name": "test",
    "products": [
        {
            "id": "01FN3Z67338ABXWMWFKEPWTBT3",
            "user_id": "user",
            "name": "test",
            "product_images": [
                {
                    "id": "1",
                    "products_id": "01FN3Z67338ABXWMWFKEPWTBT3",
                    "url": "http:///test1"
                },
                {
                    "id": "2",
                    "products_id": "01FN3Z67338ABXWMWFKEPWTBT3",
                    "url": "http:///test2"
                },
                {
                    "id": "3",
                    "products_id": "01FN3Z67338ABXWMWFKEPWTBT3",
                    "url": "http:///test3"
                }
            ],
        },
        {
            "id": "01FN3Z683VPVWP200E4GTS73SZ",
            "user_id": "user",
            "name": "test",
            "product_images": [
                {
                    "id": "4",
                    "products_id": "01FN3Z683VPVWP200E4GTS73SZ",
                    "url": "http:///test4"
                },
                {
                    "id": "5",
                    "products_id": "01FN3Z683VPVWP200E4GTS73SZ",
                    "url": "http:///test5"
                },
                {
                    "id": "6",
                    "products_id": "01FN3Z683VPVWP200E4GTS73SZ",
                    "url": "http:///test6"
                }
            ],
        }
    ]
}

参考資料

以上です!!!それでは👋

2
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
2
0