こんにちは!データベース検索を簡単にしよう
今日Goでコード書いてて、データベースから条件検索するときにつまづいたのでメモ。検索条件で「以上」「以下」を指定したいときの書き方で悩んだんだけど、解決したらめっちゃ便利だったので共有します!
squirrelライブラリとは?初心者でもわかるSQL構築ツール
squirrelはGo言語でSQLを組み立てるための超便利なライブラリです。生のSQLを書くのは面倒だし、ミスも起きやすいですよね。squirrelを使えば型安全にSQLクエリを構築できるので、開発効率がグッと上がります!
import "github.com/Masterminds/squirrel"
SQLインジェクション対策もバッチリなので、セキュリティ面でも安心です。特にWebアプリケーション開発では必須のツールと言えるでしょう。
条件検索で使える比較演算子たち
Gt - Greater Than (より大きい)
Gt
は「Greater Than」の略で、SQLの「>」演算子に相当します。「より大きい」という条件を表現します。
// IDが100より大きいレコードを取得
users := squirrel.Select("id", "name").
From("users").
Where(squirrel.Gt{
"id": 100,
})
GtOrEq - Greater Than or Equal (以上)
GtOrEq
は「Greater Than or Equal」の略で、SQLの「>=」演算子です。「以上」という条件を表します。
// created_atが7日前以降のデータを取得する
// 最近登録されたユーザーを見つけるのに便利
users := squirrel.Select("id", "name").
From("users").
Where(squirrel.GtOrEq{
"created_at": time.Now().AddDate(0, 0, -7),
})
Lt - Less Than (より小さい)
Lt
は「Less Than」の略で、SQLの「<」演算子に相当します。「より小さい」という条件を表します。
// 価格が1000円より小さい商品を取得
items := squirrel.Select("id", "name").
From("items").
Where(squirrel.Lt{
"price": 1000,
})
LtOrEq - Less Than or Equal (以下)
LtOrEq
は「Less Than or Equal」の略で、SQLの「<=」演算子です。「以下」という条件を表します。
// 値段が1000円以下の商品を取得
items := squirrel.Select("id", "name").
From("items").
Where(squirrel.LtOrEq{
"price": 1000,
})
複数条件を組み合わせて高度な検索を実現
価格範囲での検索(価格が100円以上500円以下の商品)
複数の条件を組み合わせたいときは、And{}
を使います。例えば価格範囲を指定するときはこんな感じ:
// 値段が100円以上500円以下の商品
items := squirrel.Select("*").
From("items").
Where(squirrel.And{
squirrel.GtOrEq{"price": 100},
squirrel.LtOrEq{"price": 500},
})
複合条件の例(会社IDと作成日の条件)
異なる種類の条件も簡単に組み合わせられます:
// 会社IDが3で、作成日が1週間以内のユーザー
users := squirrel.Select("*").
From("users").
Where("company_id = ?", 3).
Where(squirrel.GtOrEq{
"created_at": time.Now().AddDate(0, 0, -7),
})
実践的な使い方:ページネーションとサブクエリ
ページネーション実装
リスト表示でよく使うページネーションもsquirrelで簡単に実現できます:
// ページネーション(10件ずつ表示、2ページ目)
const pageSize = 10
const currentPage = 2
query := squirrel.Select("*").
From("products").
OrderBy("created_at DESC").
Limit(pageSize).
Offset((currentPage - 1) * pageSize)
サブクエリを使った高度なフィルタリング
より複雑な検索条件を実現するために、サブクエリも使えます:
// アクティブなカテゴリに属する商品だけを取得
subQuery := squirrel.Select("id").
From("categories").
Where(squirrel.Eq{"status": "active"})
sql, args, err := squirrel.Select("*").
From("products").
Where("category_id IN ("+subQuery.MustSql()+")", subQuery.Args()...).
ToSql()
データベース接続と実行方法
squirrelはクエリを構築するだけでなく、実行までサポートしています:
// PostgreSQLの場合(プレースホルダーの形式を変更)
psql := squirrel.StatementBuilder.
PlaceholderFormat(squirrel.Dollar)
// クエリ構築から実行まで一気に行う例
rows, err := psql.Select("id", "name").
From("users").
Where(squirrel.Eq{"active": true}).
RunWith(db).
Query()
トランザクションとの組み合わせ
より安全な操作のために、トランザクションとsquirrelを組み合わせることもできます:
// トランザクション開始
tx, err := db.Begin()
if err != nil {
return err
}
// 成功時はコミット、エラー時はロールバック
defer func() {
if err != nil {
tx.Rollback()
return
}
tx.Commit()
}()
// squirrelでクエリを構築してトランザクション内で実行
_, err = squirrel.Update("users").
Set("status", "inactive").
Where(squirrel.Eq{"id": userId}).
RunWith(tx). // ここでトランザクションを渡す
Exec()
注意点とベストプラクティス
- BETWEENを直接書けない:上の例のようにAnd{}とGtOrEq/LtOrEqを使うか、Expr()で直接SQLを書く
- 値がnilのときはIS NULL/IS NOT NULLになる:この自動変換は便利だけど意識しておく
- 配列を渡すとIN句になる:これを利用してIN句を簡潔に書ける
- プレースホルダー形式はDBに合わせて:PostgreSQLなら
Dollar
、MySQLならQuestion
を使う
まとめ:squirrelで型安全なSQL構築を
squirrelを使うと、Goの型安全性を活かしながらSQLを構築できます。今回紹介したGtOrEqとLtOrEqは「以上」「以下」の条件を書くときに特に便利です。複数条件はAnd{}やOr{}で組み合わせることで、複雑なクエリも簡潔に表現できます。
型安全かつ読みやすいコードで、SQLインジェクションなどのセキュリティリスクも軽減できるので、ぜひ活用してみてください!