スマートセレクトフィールド
GORM では、Select
メソッドを使用して、特定のフィールドを効率的に選択できます。これは、特に API レスポンスで、大きなモデルを扱うものの、フィールドのサブセットのみを必要とする場合に特に役立ちます。
type User struct { |
注
QueryFields
モードでは、すべてのモデルフィールドが名前で選択されます。
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{ |
ロック
GORM は、さまざまな種類のロックをサポートしています。例えば
// Basic FOR UPDATE lock |
上記のステートメントは、トランザクションの間、選択された行をロックします。これは、行を更新する準備をしていて、トランザクションが完了するまで他のトランザクションがそれらを変更するのを防ぎたいシナリオで使用できます。
Strength
は SHARE
に設定することもでき、これにより、他のトランザクションがロックされた行を読み取れるようにロックしますが、更新または削除はできません。
db.Clauses(clause.Locking{ |
Table
オプションは、ロックするテーブルを指定するために使用できます。これは、複数のテーブルを結合していて、そのうちの 1 つだけをロックしたい場合に便利です。
オプションには、NOWAIT
のように、ロックの取得を試み、ロックが利用できない場合はすぐにエラーで失敗するものがあります。これにより、トランザクションが他のトランザクションがロックを解放するのを待つことを防ぎます。
db.Clauses(clause.Locking{ |
別のオプションとして、SKIP LOCKED
があります。これは、他のトランザクションによってすでにロックされている行をスキップします。これは、他のトランザクションによって現在ロックされていない行を処理したい高並行状況で役立ちます。
より高度なロック戦略については、生の SQL および SQL ビルダーを参照してください。
サブクエリ
サブクエリは、SQL の強力な機能で、ネストされたクエリを可能にします。GORM は、*gorm.DB オブジェクトをパラメータとして使用すると、サブクエリを自動的に生成できます。
// Simple subquery |
FROM サブクエリ
GORM では、FROM 句でサブクエリを使用でき、複雑なクエリとデータの編成が可能になります。
// Using subquery in FROM clause |
グループ条件
GORM のグループ条件は、複数の条件を含む複雑な SQL クエリを作成するための、より読みやすく保守しやすい方法を提供します。
// Complex SQL query using Group Conditions |
複数列の IN
GORM は、複数の列を持つ IN 句をサポートしており、単一のクエリで複数のフィールド値に基づいてデータをフィルタリングできます。
// Using IN with multiple columns |
名前付き引数
GORM は、名前付き引数をサポートすることで、SQL クエリの可読性と保守性を向上させます。この機能により、特に複数のパラメータを持つ複雑なクエリで、より明確で整理されたクエリ構築が可能になります。名前付き引数は、sql.NamedArg
または map[string]interface{}{}
のいずれかを使用して利用でき、クエリの構造化方法に柔軟性を提供します。
// Example using sql.NamedArg for named arguments |
詳細な例については、生の SQL および SQL ビルダーを参照してください。
マップへの検索
GORM は、結果を map[string]interface{}
または []map[string]interface{}
にスキャンできるようにすることで、データのクエリに柔軟性を提供します。これは、動的なデータ構造に役立ちます。
マップへの検索
を使用する場合は、クエリに Model
または Table
を含めてテーブル名を明示的に指定することが重要です。これにより、GORM がどのテーブルに対してクエリを実行するかを確実に理解できます。
// Scanning the first result into a map with Model |
FirstOrInit
GORM の FirstOrInit
メソッドは、指定された条件に一致する最初のレコードを取得するか、一致するレコードが見つからない場合は新しいインスタンスを初期化するために使用されます。このメソッドは、struct 条件と map 条件の両方と互換性があり、Attrs
および Assign
メソッドを使用することでさらに柔軟性が高まります。
// If no User with the name "non_existing" is found, initialize a new User |
初期化に Attrs
を使用する
レコードが見つからない場合は、Attrs
を使用して、追加の属性で struct を初期化できます。これらの属性は新しい struct に含まれますが、SQL クエリでは使用されません。
// If no User is found, initialize with given conditions and additional attributes |
属性に Assign
を使用する
Assign
メソッドを使用すると、レコードが見つかったかどうかに関係なく、struct に属性を設定できます。これらの属性は struct に設定されますが、SQL クエリの構築には使用されず、最終的なデータはデータベースに保存されません。
// Initialize with given conditions and Assign attributes, regardless of record existence |
FirstOrInit
は、Attrs
および Assign
と共に、レコードが存在し、特定の属性で初期化または更新されることを単一のステップで保証するための、強力で柔軟な方法を提供します。
FirstOrCreate
GORM の FirstOrCreate
は、指定された条件に一致する最初のレコードを取得するか、一致するレコードが見つからない場合は新しいレコードを作成するために使用されます。このメソッドは、struct 条件と map 条件の両方で効果的です。RowsAffected
プロパティは、作成または更新されたレコードの数を判断するのに役立ちます。
// Create a new record if not found |
FirstOrCreate で Attrs
を使用する
Attrs
を使用して、新しいレコードが見つからない場合に追加の属性を指定できます。これらの属性は作成に使用されますが、最初の検索クエリでは使用されません。
// Create a new record with additional attributes if not found |
FirstOrCreate で Assign
を使用する
Assign
メソッドは、レコードが見つかったかどうかに関係なくレコードに属性を設定し、これらの属性はデータベースに保存されます。
// Initialize and save new record with `Assign` attributes if not found |
オプティマイザ/インデックスヒント
GORM には、オプティマイザとインデックスヒントのサポートが含まれており、クエリオプティマイザの実行計画に影響を与えることができます。これは、クエリのパフォーマンスを最適化したり、複雑なクエリを処理したりする場合に特に役立ちます。
オプティマイザヒントは、データベースのクエリオプティマイザがクエリを実行する方法を提案する指示です。GORM は、gorm.io/hints パッケージを通じてオプティマイザヒントの使用を容易にします。
import "gorm.io/hints" |
インデックスヒント
インデックスヒントは、使用するインデックスに関するガイダンスをデータベースに提供します。クエリプランナーがクエリに最も効率的なインデックスを選択していない場合に役立ちます。
import "gorm.io/hints" |
これらのヒントは、特に大規模なデータベースや複雑なデータモデルでは、クエリのパフォーマンスと動作に大きな影響を与える可能性があります。詳細情報と追加の例については、GORM ドキュメントの オプティマイザヒント/インデックス/コメント を参照してください。
反復処理
GORM は、Rows
メソッドを使用してクエリ結果の反復処理をサポートしています。この機能は、大規模なデータセットを処理したり、各レコードで個別に操作を実行する必要がある場合に特に役立ちます。
クエリによって返された行を反復処理し、各行を struct にスキャンできます。このメソッドは、各レコードの処理方法を詳細に制御できます。
rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Rows() |
このアプローチは、標準のクエリメソッドでは簡単に実現できない複雑なデータ処理に最適です。
FindInBatches
FindInBatches
を使用すると、レコードをバッチでクエリして処理できます。これは、大規模なデータセットを効率的に処理し、メモリ使用量を削減し、パフォーマンスを向上させるのに特に役立ちます。
FindInBatches
では、GORM は指定されたバッチサイズでレコードを処理します。バッチ処理関数内で、レコードの各バッチに操作を適用できます。
// Processing records in batches of 100 |
FindInBatches
は、管理可能なチャンクで大量のデータを処理し、リソースの使用とパフォーマンスを最適化するための効果的なツールです。
クエリフック
GORM は、クエリのライフサイクル中にトリガーされる AfterFind
などのフックを使用する機能を提供します。これらのフックにより、データベースからレコードが取得された後など、特定の時点でカスタムロジックを実行できます。
このフックは、クエリ後のデータ操作やデフォルト値の設定に役立ちます。詳細情報と追加のフックタイプについては、GORM ドキュメントの フック を参照してください。
func (u *User) AfterFind(tx *gorm.DB) (err error) { |
Pluck
GORM の Pluck
メソッドは、データベースから単一の列をクエリし、結果をスライスにスキャンするために使用されます。このメソッドは、モデルから特定のフィールドを取得する必要がある場合に最適です。
複数の列をクエリする必要がある場合は、代わりに Scan または Find と共に Select
を使用できます。
// Retrieving ages of all users |
スコープ
GORM の Scopes
は、一般的に使用されるクエリ条件を再利用可能なメソッドとして定義できる強力な機能です。これらのスコープはクエリで簡単に参照できるため、コードがよりモジュール化され、読みやすくなります。
スコープの定義
Scopes
は、gorm.DB
インスタンスを変更して返す関数として定義されます。アプリケーションの要件に基づいて、さまざまな条件をスコープとして定義できます。
// Scope for filtering records where amount is greater than 1000 |
クエリでのスコープの適用
Scopes
メソッドを使用して、1 つ以上のスコープをクエリに適用できます。これにより、複数の条件を動的にチェーンできます。
// Applying scopes to find all credit card orders with an amount greater than 1000 |
Scopes
は、共通のクエリロジックをカプセル化するためのクリーンで効率的な方法であり、コードの保守性と可読性を向上させます。詳細な例と使用法については、GORMドキュメントのスコープを参照してください。
Count
GORMのCount
メソッドは、特定のクエリに一致するレコード数を取得するために使用されます。これは、条件付きクエリやデータ分析を伴うシナリオにおいて、データセットのサイズを把握するための便利な機能です。
一致するレコード数の取得
Count
を使用して、クエリで特定の条件を満たすレコードの数を判定できます。
var count int64 |
DistinctおよびGroupを使用したCount
GORMでは、重複しない値のカウントや結果のグループ化も可能です。
// Counting distinct names |