智慧選擇欄位
在 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
選項可用於指定要鎖定的表格。這在連接多個表格且只想鎖定其中一個表格時很有用。
選項可以提供像是 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 建構器
查詢到 Map
GORM 提供查詢資料的彈性,允許將結果掃描到 map[string]interface{}
或 []map[string]interface{}
,這對於動態資料結構很有用。
在使用 查詢到 Map
時,在查詢中包含 Model
或 Table
以明確指定資料表名稱至關重要。這可確保 GORM 了解要針對哪個資料表進行查詢。
// Scanning the first result into a map with Model |
FirstOrInit
GORM 的 FirstOrInit
方法用於擷取與給定條件相符的第一筆記錄,或在找不到相符記錄時初始化新的執行個體。此方法與結構和 Map 條件相容,並允許使用 Attrs
和 Assign
方法提供額外的彈性。
// If no User with the name "non_existing" is found, initialize a new User |
使用 Attrs
初始化
找不到記錄時,可以使用 Attrs
來初始化具有其他屬性的結構。這些屬性包含在新結構中,但不會用於 SQL 查詢。
// If no User is found, initialize with given conditions and additional attributes |
使用 Assign
進行屬性
Assign
方法允許您設定結構上的屬性,無論是否找到記錄。這些屬性會設定在結構上,但不會用於建立 SQL 查詢,最終資料也不會儲存到資料庫中。
// Initialize with given conditions and Assign attributes, regardless of record existence |
FirstOrInit
搭配 Attrs
和 Assign
,提供一種強大且彈性的方式,可確保記錄存在,並在單一步驟中使用特定屬性進行初始化或更新。
FirstOrCreate
GORM 中的 FirstOrCreate
用於擷取符合給定條件的第一個記錄,或是在找不到符合記錄時建立一個新的記錄。此方法對於結構和對應條件都很有效。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
方法反覆運算查詢結果。此功能在需要處理大型資料集或個別對每個記錄執行作業時特別有用。
您可以反覆運算查詢傳回的列,將每個列掃描到結構中。此方法提供對每個記錄處理方式的細微控制。
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
方法用於從資料庫查詢單一欄,並將結果掃描到區段中。當您需要從模型擷取特定欄位時,此方法非常理想。
如果您需要查詢多個欄位,您可以改用 Select
搭配 Scan 或 Find。
// Retrieving ages of all users |
範圍
GORM 中的 Scopes
是一項強大的功能,允許您將常用的查詢條件定義為可重複使用的函式。這些範圍可以在您的查詢中輕鬆參照,讓您的程式碼更具模組化和可讀性。
定義範圍
Scopes
定義為修改並傳回 gorm.DB
執行個體的函式。您可以根據應用程式的需求定義各種條件作為範圍。
// Scope for filtering records where amount is greater than 1000 |
應用範圍於查詢
您可以使用 Scopes
方法將一個或多個範圍應用於查詢。這允許您動態串聯多個條件。
// Applying scopes to find all credit card orders with an amount greater than 1000 |
Scopes
是一種乾淨且有效的方法,可封裝常見的查詢邏輯,增強程式碼的可維護性和可讀性。有關更詳細的範例和用法,請參閱 GORM 文件中的 Scopes。
計數
GORM 中的 Count
方法用於擷取與給定查詢相符的記錄數。這是一個有用的功能,用於了解資料集的大小,特別是在涉及條件查詢或資料分析的場景中。
取得相符記錄的計數
您可以在查詢中使用 Count
來確定符合特定條件的記錄數。
var count int64 |
使用 Distinct 和 Group 計數
GORM 也允許計數相異值和群組結果。
// Counting distinct names |