LoginSignup
5
1

【Go】Gormでクエリーの結果を構造体に詰めたいけど何を使えばいいんだっけ?ってよくなるのでまとめました

Last updated at Posted at 2024-05-27

はじめに

普段の開発でORMにGormを採用しているのですが、クエリー結果を構造体へ詰めるために、FirstTakeFindのどれを使えばいいのかついつい忘れちゃうことがありました。また、条件に合うレコードが見つからなかった場合にTakeはエラーを返した気がするけど、Findはどうだっけ...ともなっていたので、今回備忘録がてらまとめてみました。

結論

単体オブジェクトを取得したい場合は、Take, First, Lastを使い、複数オブジェクトを取得したい場合は、Find, Scanを使う。
First, Take, Lastは条件に合うレコードが存在しなかった場合、ErrRecordNotFoundを返却するが、Find, Scanは何も返さない。

Find, Scanは単体オブジェクトに対しても使用可能です。
db.Limit(1).Find(&user)とすることで、Takeと同様のSQLが流れますが、エラーは返りません。
以下で詳しく説明していきます。

First

Firstはprimary keyでorderして条件に合う最初のレコードを返却します。
また、レコードが見つからない場合は、ErrRecordNotFoundを返却します。

db.Where("name = ?", "jinzhu").First(&user)
//=> SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;

Take

Takeはorderせずランダムに1レコードを取得します。
また、レコードが見つからない場合は、ErrRecordNotFoundを返却します

db.Where("name = ?", "jinzhu").First(&user)
//=> SELECT * FROM users WHERE name = 'jinzhu' LIMIT 1;

Last

Lastはprimary keyで逆順にorderして条件に合う最後のレコードを返却します。また、レコードが見つからない場合は、ErrRecordNotFoundを返却します。

db.Where("name = ?", "jinzhu").Last(&user)
//=> SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id DESC LIMIT 1;

Find

Findは条件に合うすべてのレコードを取得します。単体オブジェクトに対しても使用可能で、エラーは返りません。

db.Where("name = ?", "jinzhu").Find(&users)
//=> SELECT * FROM users WHERE name = 'jinzhu';

単体オブジェクトに対して使用する場合は、db.Limit(1).Find(&user)のようにします。この場合、条件に合うレコードが存在しなくてもエラーは返らず、空のオブジェクトが返されます。

Scan

Scanは条件に合うすべてのレコードを取得し、特定のフィールドのみを構造体にマッピングします。通常はクエリの結果を別の構造体へマッピングするために使用されます。単体オブジェクトに対しても使用可能で、エラーは返りません。

type Result struct {
    Name string
    Age  int
}

var result Result
db.Table("users").Select("name, age").Where("name = ?", "jinzhu").Scan(&result)
//=> SELECT name, age FROM users WHERE name = 'jinzhu';

終わりに

Gormは公式ドキュメントが豊富で、日本語版も充実しているのでよかったら読んでみてください。

5
1
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
5
1