2026.01.19
GORMで「検索条件が効かない!?」と焦った話。構造体検索の落とし穴と解決策
2026.01.19
GoGORMで「検索条件が効かない!?」と焦った話。構造体検索の落とし穴と解決策

Go言語で開発をしていて、DB操作にGORMを使っている方は多いですよね。
直感的に書けて便利なGORMですが、実は初心者がハマりやすい「意外な仕様」があるんです。
「ちゃんと条件を指定したはずなのに、なぜか意図しないデータが取れてしまう」 そんなときにチェックしてほしい(私がハマってしまった)ポイントをまとめました。
たとえば、IDを指定してユーザー情報を1件探す、こんなシンプルなメソッドを考えてみます。
func (u *User) FindByID(db *gorm.DB, id string) error {
// 構造体にIDをセットして検索!
u.ID = id
return db.First(u).Error
}
一見、何の問題もなさそうに見えますが、実は id が何らかの理由で空っぽ(””)だったときに、大きなバグが発生します。
実はGORMには、
「構造体のフィールドが空(ゼロ値)だったら、検索条件には入れないよ!」
というルールがあるんです。
もし id が空文字 "" だった場合、GORMは「IDは未設定(ゼロ値)なんだな」と判断して、勝手に条件から外してしまいます。
SELECT * FROM users WHERE id = "" LIMIT 1;(→普通はデータなしでエラーになるはず) SELECT * FROM users ORDER BY id LIMIT 1;つまり、
「IDは何でもいいから、とりあえず一番上の人を連れてきて!」
というクエリに変わってしまうんです。
本来「該当なし」のエラーになるべきところで、「たまたまDBの先頭にいた別の人」のデータが取れて、そのまま画面に表示されてしまう……。
これ、個人情報の扱いやセキュリティを考えると、かなりヒヤッとしますよね。
空文字("")や数値の 0 も含めて、しっかり条件に入れてほしいときは、以下の書き方が「正解」です!
IDを指定する場合は、構造体にセットせず、First メソッドの第2引数で直接渡します。
// 推奨:これならIDが空でも正しく「データなし(RecordNotFound)」になります
func (u *User) FindByID(db *gorm.DB, id string) error {
return db.First(u, "id = ?", id).Error
}
role や group など、複数の条件で探したいときも、構造体ではなくMapを使うのが一番安全です。
// 推奨:Map形式なら、空文字も「検索条件」として扱ってくれます
func (u *User) FindByRoleAndGroup(db *gorm.DB, role string, group string) error {
return db.Where(map[string]interface{}{
"role": role,
"group": group,
}).First(u).Error
}
GORMの構造体検索がダメなわけではありません。
「入力された項目があるときだけ絞り込む」みたいな「検索フォーム」を作るときには、今の仕様が便利だったりします。
でも、「特定のデータを厳密に特定したい」場面では、使い分けが大切です!
私はこの辺りの理解ができておらず、一人であせあせしていました!
仕様は正しく理解して扱っていきましょうね!
【記事への感想募集中!】
記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!【テクノデジタルではエンジニア/デザイナーを積極採用中です!】
下記項目に1つでも当てはまる方は是非、詳細ページへ!Qangaroo(カンガルー)
【テクノデジタルのインフラサービス】
当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。
最近の記事
タグ検索