便利なフィールドの選択
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つだけをロックしたい場合に便利です。
Optionsには NOWAIT
などを入力できます。この場合、ロックが利用できないタイミングでロックをかけようとすると、すぐにエラーが発生します。 ほかのトランザクションがロックを解除するまで待機することがなくなります。
db.Clauses(clause.Locking{ |
オプションにはもう1つ SKIP LOCKED
もあります。これは、ほかのトランザクションによってすでにロックされている行をすべてスキップします。 これは、トランザクションによって現在ロックされていない行を処理したい場合など、同時実効性が高いケースにおいて便利です。
ロックを使ったより高度な戦略については、Raw SQL and SQL Builder を参照してください。
サブクエリ
サブクエリはSQLの強力な機能で、クエリのネストを可能にします。 パラメータに *gorm.DB オブジェクトを使用すると、GORMは自動的にサブクエリを生成します。
// Simple subquery |
From句でのサブクエリ
GORM allows the use of subqueries in the FROM clause, enabling complex queries and data organization.
// Using subquery in FROM clause |
条件をグループ化する
GORMのグループ条件は、複数の条件を含む複雑なSQLクエリの可読性およびメンテナンス性の向上をもたらします。
// Complex SQL query using Group Conditions |
複数カラムでのIN
GORMは複数カラムでのIN句をサポートしており、1つのクエリで複数のフィールド値に基づいたデータのフィルタリングが行えます。
// Using IN with multiple columns |
名前付き引数
GORMは名前付き引数をサポートしており、SQLクエリの可読性とメンテナンス性を向上させています。 この機能により、特に複数のパラメータを持つ複雑なクエリにおいては、よりクリアかつ整理されたクエリ構造が可能となっています。 名前付き引数は sql.NamedArg
または map[string]interface{}{}
のいずれかを使用することで有効になり、クエリの構成に柔軟性をもたらします。
// Example using sql.NamedArg for named arguments |
その他の例や詳細については Raw SQL and SQL Builder を参照してください。
取得結果をマップに代入
GORM provides flexibility in querying data by allowing results to be scanned into a map[string]interface{}
or []map[string]interface{}
, which can be useful for dynamic data structures.
When using Find To Map
, it’s crucial to include Model
or Table
in your query to explicitly specify the table name. This ensures that GORM understands which table to query against.
// Scanning the first result into a map with Model |
FirstOrInit
GORM’s FirstOrInit
method is utilized to fetch the first record that matches given conditions, or initialize a new instance if no matching record is found. This method is compatible with both struct and map conditions and allows additional flexibility with the Attrs
and Assign
methods.
// If no User with the name "non_existing" is found, initialize a new User |
Using Attrs
for Initialization
When no record is found, you can use Attrs
to initialize a struct with additional attributes. These attributes are included in the new struct but are not used in the SQL query.
// If no User is found, initialize with given conditions and additional attributes |
Using Assign
for Attributes
The Assign
method allows you to set attributes on the struct regardless of whether the record is found or not. These attributes are set on the struct but are not used to build the SQL query and the final data won’t be saved into the database.
// Initialize with given conditions and Assign attributes, regardless of record existence |
FirstOrInit
, along with Attrs
and Assign
, provides a powerful and flexible way to ensure a record exists and is initialized or updated with specific attributes in a single step.
FirstOrCreate
FirstOrCreate
in GORM is used to fetch the first record that matches given conditions or create a new one if no matching record is found. This method is effective with both struct and map conditions. The RowsAffected
property is useful to determine the number of records created or updated.
// Create a new record if not found |
Using Attrs
with FirstOrCreate
Attrs
can be used to specify additional attributes for the new record if it is not found. These attributes are used for creation but not in the initial search query.
// Create a new record with additional attributes if not found |
Using Assign
with FirstOrCreate
The Assign
method sets attributes on the record regardless of whether it is found or not, and these attributes are saved back to the database.
// Initialize and save new record with `Assign` attributes if not found |
Optimizer/Index Hints
GORM includes support for optimizer and index hints, allowing you to influence the query optimizer’s execution plan. This can be particularly useful in optimizing query performance or when dealing with complex queries.
Optimizer hints are directives that suggest how a database’s query optimizer should execute a query. GORM facilitates the use of optimizer hints through the gorm.io/hints package.
import "gorm.io/hints" |
Index Hints
Index hints provide guidance to the database about which indexes to use. They can be beneficial if the query planner is not selecting the most efficient indexes for a query.
import "gorm.io/hints" |
These hints can significantly impact query performance and behavior, especially in large databases or complex data models. For more detailed information and additional examples, refer to Optimizer Hints/Index/Comment in the GORM documentation.
Iteration
GORM は、クエリ結果を反復処理できる Rows
メソッド をサポートしています。 This feature is particularly useful when you need to process large datasets or perform operations on each record individually.
You can iterate through rows returned by a query, scanning each row into a struct. This method provides granular control over how each record is handled.
rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Rows() |
This approach is ideal for complex data processing that cannot be easily achieved with standard query methods.
FindInBatches
FindInBatches
allows querying and processing records in batches. This is especially useful for handling large datasets efficiently, reducing memory usage and improving performance.
With FindInBatches
, GORM processes records in specified batch sizes. Inside the batch processing function, you can apply operations to each batch of records.
// Processing records in batches of 100 |
。
Query Hooks
GORM offers the ability to use hooks, such as AfterFind
, which are triggered during the lifecycle of a query. These hooks allow for custom logic to be executed at specific points, such as after a record has been retrieved from the database.
This hook is useful for post-query data manipulation or default value settings. For more detailed information and additional hook types, refer to Hooks in the GORM documentation.
func (u *User) AfterFind(tx *gorm.DB) (err error) { |
Pluck
The Pluck
method in GORM is used to query a single column from the database and scan the result into a slice. This method is ideal for when you need to retrieve specific fields from a model.
If you need to query more than one column, you can use Select
with Scan or Find instead.
// Retrieving ages of all users |
Scopes
Scopes
in GORM are a powerful feature that allows you to define commonly-used query conditions as reusable methods. These scopes can be easily referenced in your queries, making your code more modular and readable.
Defining Scopes
Scopes
are defined as functions that modify and return a gorm.DB
instance. You can define a variety of conditions as scopes based on your application’s requirements.
// Scope for filtering records where amount is greater than 1000 |
Applying Scopes in Queries
You can apply one or more scopes to a query by using the Scopes
method. This allows you to chain multiple conditions dynamically.
// Applying scopes to find all credit card orders with an amount greater than 1000 |
Scopes
are a clean and efficient way to encapsulate common query logic, enhancing the maintainability and readability of your code. For more detailed examples and usage, refer to Scopes in the GORM documentation.
Count
The Count
method in GORM is used to retrieve the number of records that match a given query. It’s a useful feature for understanding the size of a dataset, particularly in scenarios involving conditional queries or data analysis.
Getting the Count of Matched Records
You can use Count
to determine the number of records that meet specific criteria in your queries.
var count int64 |
Count with Distinct and Group
GORM also allows counting distinct values and grouping results.
// 重複しない名前の数をカウント |