<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 高級查詢 ## 智能選擇字段 GORM 允許通過 [`Select`](http://v2.gorm.io/zh_CN/docs/query.html) 方法選擇特定的字段,如果您在應用程序中經常使用此功能,你可以定義一個較小的 API 結構體,以實現自動選擇特定的字段。 ```go type User struct { ID uint Name string Age int Gender string // 假設后面還有幾百個字段... } type APIUser struct { ID uint Name string } // 查詢時會自動選擇 `id`, `name` 字段 db.Model(&User{}).Limit(10).Find(&APIUser{}) // SELECT `id`, `name` FROM `users` LIMIT 10 ``` ## Locking (FOR UPDATE) GORM 支持多種類型的鎖,例如: ```go DB.Clauses(clause.Locking{Strength: "UPDATE"}).Find(&users) // SELECT * FROM `users` FOR UPDATE DB.Clauses(clause.Locking{ Strength: "SHARE", Table: clause.Table{Name: clause.CurrentTable}, }).Find(&users) // SELECT * FROM `users` FOR SHARE OF `users` ``` 參考 [原生 SQL 及構造器](./sql_builder.md) 獲取詳情 ## 子查詢 子查詢可以嵌套在查詢中,GORM 允許在使用 `*gorm.DB` 對象作為參數時生成子查詢 ```go db.Where("amount > ?", db.Table("orders").Select("AVG(amount)")).Find(&orders) // SELECT * FROM "orders" WHERE amount > (SELECT AVG(amount) FROM "orders"); subQuery := db.Select("AVG(age)").Where("name LIKE ?", "name%").Table("users") db.Select("AVG(age) as avgage").Group("name").Having("AVG(age) > (?)", subQuery).Find(&results) // SELECT AVG(age) as avgage FROM `users` GROUP BY `name` HAVING AVG(age) > (SELECT AVG(age) FROM `users` WHERE name LIKE "name%") ``` ### From 子查詢 GORM 允許您在 `Table` 方法中通過 FROM 子句使用子查詢,例如: ```go db.Table("(?) as u", DB.Model(&User{}).Select("name", "age")).Where("age = ?", 18}).Find(&User{}) // SELECT * FROM (SELECT `name`,`age` FROM `users`) as u WHERE `age` = 18 subQuery1 := DB.Model(&User{}).Select("name") subQuery2 := DB.Model(&Pet{}).Select("name") db.Table("(?) as u, (?) as p", subQuery1, subQuery2).Find(&User{}) // SELECT * FROM (SELECT `name` FROM `users`) as u, (SELECT `name` FROM `pets`) as p ``` ## Group 條件 使用 Group 條件可以更輕松的編寫復雜 SQL ```go db.Where( DB.Where("pizza = ?", "pepperoni").Where(DB.Where("size = ?", "small").Or("size = ?", "medium")), ).Or( DB.Where("pizza = ?", "hawaiian").Where("size = ?", "xlarge"), ).Find(&Pizza{}).Statement // SELECT * FROM `pizzas` WHERE (pizza = "pepperoni" AND (size = "small" OR size = "medium")) OR (pizza = "hawaiian" AND size = "xlarge") ``` ## 命名參數 GORM 支持 [`sql.NamedArg`](https://tip.golang.org/pkg/database/sql/#NamedArg) 和 `map[string]interface{}{}` 形式的命名參數,例如: ```go DB.Where("name1 = @name OR name2 = @name", sql.Named("name", "jinzhu")).Find(&user) // SELECT * FROM `users` WHERE name1 = "jinzhu" OR name2 = "jinzhu" DB.Where("name1 = @name OR name2 = @name", map[string]interface{}{"name": "jinzhu"}).First(&user) // SELECT * FROM `users` WHERE name1 = "jinzhu" OR name2 = "jinzhu" ORDER BY `users`.`id` LIMIT 1 ``` 查看 [原生 SQL 及構造器](./sql_builder.md#named_argument) 獲取詳情 ## Find 至 map GORM 允許掃描結果至 `map[string]interface{}` 或 `[]map[string]interface{}`,此時別忘了指定 `Model` 或 `Table`,例如: ```go var result map[string]interface{} DB.Model(&User{}).First(&result, "id = ?", 1) var results []map[string]interface{} DB.Table("users").Find(&results) ``` ## FirstOrInit 獲取第一條匹配的記錄,或者根據給定的條件初始化一個 struct(僅支持 sturct 和 map 條件) ```go // 未找到 user,根據給定的條件初始化 struct db.FirstOrInit(&user, User{Name: "non_existing"}) // user -> User{Name: "non_existing"} // 找到了 `name` = `jinzhu` 的 user db.Where(User{Name: "jinzhu"}).FirstOrInit(&user) // user -> User{ID: 111, Name: "Jinzhu", Age: 18} // 找到了 `name` = `jinzhu` 的 user db.FirstOrInit(&user, map[string]interface{}{"name": "jinzhu"}) // user -> User{ID: 111, Name: "Jinzhu", Age: 18} ``` 如果沒有找到記錄,可以使用包含更多的屬性的結構體初始化 user,`Attrs` 不會被用于生成查詢 SQL ```go // 未找到 user,則根據給定的條件以及 Attrs 初始化 user db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrInit(&user) // SELECT * FROM USERS WHERE name = 'non_existing' ORDER BY id LIMIT 1; // user -> User{Name: "non_existing", Age: 20} // 未找到 user,則根據給定的條件以及 Attrs 初始化 user db.Where(User{Name: "non_existing"}).Attrs("age", 20).FirstOrInit(&user) // SELECT * FROM USERS WHERE name = 'non_existing' ORDER BY id LIMIT 1; // user -> User{Name: "non_existing", Age: 20} // 找到了 `name` = `jinzhu` 的 user,則忽略 Attrs db.Where(User{Name: "Jinzhu"}).Attrs(User{Age: 20}).FirstOrInit(&user) // SELECT * FROM USERS WHERE name = jinzhu' ORDER BY id LIMIT 1; // user -> User{ID: 111, Name: "Jinzhu", Age: 18} ``` 不管是否找到記錄,`Assign` 都會將屬性賦值給 struct,但這些屬性不會被用于生成查詢 SQL ```go // 未找到 user,根據條件和 Assign 屬性初始化 struct db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrInit(&user) // user -> User{Name: "non_existing", Age: 20} // 找到 `name` = `jinzhu` 的記錄,依然會更新 Assign 相關的屬性 db.Where(User{Name: "Jinzhu"}).Assign(User{Age: 20}).FirstOrInit(&user) // SELECT * FROM USERS WHERE name = jinzhu' ORDER BY id LIMIT 1; // user -> User{ID: 111, Name: "Jinzhu", Age: 20} ``` ## FirstOrCreate 獲取第一條匹配的記錄,或者根據給定的條件創建一條新紀錄(僅支持 sturct 和 map 條件) ```go // 未找到 user,則根據給定條件創建一條新紀錄 db.FirstOrCreate(&user, User{Name: "non_existing"}) // INSERT INTO "users" (name) VALUES ("non_existing"); // user -> User{ID: 112, Name: "non_existing"} // 找到了 `name` = `jinzhu` 的 user db.Where(User{Name: "jinzhu"}).FirstOrCreate(&user) // user -> User{ID: 111, Name: "jinzhu", "Age}: 18 ``` 如果沒有找到記錄,可以使用包含更多的屬性的結構體創建記錄,`Attrs` 不會被用于生成查詢 SQL 。 ```go // 未找到 user,根據條件和 Assign 屬性創建記錄 db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrCreate(&user) // SELECT * FROM users WHERE name = 'non_existing' ORDER BY id LIMIT 1; // INSERT INTO "users" (name, age) VALUES ("non_existing", 20); // user -> User{ID: 112, Name: "non_existing", Age: 20} // 找到了 `name` = `jinzhu` 的 user,則忽略 Attrs db.Where(User{Name: "jinzhu"}).Attrs(User{Age: 20}).FirstOrCreate(&user) // SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1; // user -> User{ID: 111, Name: "jinzhu", Age: 18} ``` 不管是否找到記錄,`Assign` 都會將屬性賦值給 struct,并將結果寫回數據庫 ```go // 未找到 user,根據條件和 Assign 屬性創建記錄 db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrCreate(&user) // SELECT * FROM users WHERE name = 'non_existing' ORDER BY id LIMIT 1; // INSERT INTO "users" (name, age) VALUES ("non_existing", 20); // user -> User{ID: 112, Name: "non_existing", Age: 20} // 找到了 `name` = `jinzhu` 的 user,依然會根據 Assign 更新記錄 db.Where(User{Name: "jinzhu"}).Assign(User{Age: 20}).FirstOrCreate(&user) // SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1; // UPDATE users SET age=20 WHERE id = 111; // user -> User{ID: 111, Name: "jinzhu", Age: 20} ``` ## 優化器、索引提示 優化器提示允許我們控制查詢優化器選擇某個查詢執行計劃。 ```go import "gorm.io/hints" DB.Clauses(hints.New("MAX_EXECUTION_TIME(10000)")).Find(&User{}) // SELECT * /*+ MAX_EXECUTION_TIME(10000) */ FROM `users` ``` 索引提示允許傳遞索引提示到數據庫,以防查詢計劃器出現混亂。 ```go import "gorm.io/hints" DB.Clauses(hints.UseIndex("idx_user_name")).Find(&User{}) // SELECT * FROM `users` USE INDEX (`idx_user_name`) DB.Clauses(hints.ForceIndex("idx_user_name", "idx_user_id").ForJoin()).Find(&User{}) // SELECT * FROM `users` FORCE INDEX FOR JOIN (`idx_user_name`,`idx_user_id`)" ``` 參考 [優化器提示、索引、備注](http://v2.gorm.io/zh_CN/docs/hints.html) 獲取詳情 ## 迭代 GORM 支持通過行進行迭代 ```go rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Rows() defer rows.Close() for rows.Next() { var user User // ScanRows 將一行記錄掃描至 user db.ScanRows(rows, &user) // 業務邏輯... } ``` ## FindInBatches 用于批量查詢并處理記錄 ```go // 每次批量處理 100 條 result := DB.Where("processed = ?", false).FindInBatches(&results, 100, func(tx *gorm.DB, batch int) error { for _, result := range results { // 批量處理找到的記錄 } tx.Save(&results) tx.RowsAffected // 本次批量操作影響的記錄數 batch // Batch 1, 2, 3 // 如果返回錯誤會終止后續批量操作 return nil }) result.Error // returned error result.RowsAffected // 整個批量操作影響的記錄數 ``` ## 查詢鉤子 對于查詢操作,GORM 支持 `AfterFind` 鉤子,查詢記錄后會調用它,詳情請參考 [鉤子](http://v2.gorm.io/zh_CN/docs/hooks.html) ```go func (u *User) AfterFind(tx *gorm.DB) (err error) { if u.Role == "" { u.Role = "user" } return } ``` ## Pluck Pluck 用于從數據庫查詢單個列,并將結果掃描到切片。如果您想要查詢多列,您應該使用 [`Scan`](http://v2.gorm.io/zh_CN/docs/advanced_query.html#scan) ```go var ages []int64 db.Find(&users).Pluck("age", &ages) var names []string db.Model(&User{}).Pluck("name", &names) db.Table("deleted_users").Pluck("name", &names) // Distinct Pluck DB.Model(&User{}).Distinct().Pluck("Name", &names) // SELECT DISTINCT `name` FROM `users` // 超過一列的查詢,應該使用 `Scan` 或者 `Find`,例如: db.Select("name", "age").Scan(&users) db.Select("name", "age").Find(&users) ``` ## Scopes `Scopes` 允許你指定常用的查詢,可以在調用方法時引用這些查詢 ```go func AmountGreaterThan1000(db *gorm.DB) *gorm.DB { return db.Where("amount > ?", 1000) } func PaidWithCreditCard(db *gorm.DB) *gorm.DB { return db.Where("pay_mode_sign = ?", "C") } func PaidWithCod(db *gorm.DB) *gorm.DB { return db.Where("pay_mode_sign = ?", "C") } func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB { return func (db *gorm.DB) *gorm.DB { return db.Where("status IN (?)", status) } } db.Scopes(AmountGreaterThan1000, PaidWithCreditCard).Find(&orders) // 查找所有金額大于 1000 的信用卡訂單 db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&orders) // 查找所有金額大于 1000 的貨到付款訂單 db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders) // 查找所有金額大于 1000 且已付款或已發貨的訂單 ``` ## Count Count 用于獲取匹配的記錄數 ```go var count int64 db.Model(&User{}).Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Count(&count) // SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2' db.Model(&User{}).Where("name = ?", "jinzhu").Count(&count) // SELECT count(*) FROM users WHERE name = 'jinzhu'; (count) db.Table("deleted_users").Count(&count) // SELECT count(*) FROM deleted_users; // 去重計數 DB.Model(&User{}).Distinct("name").Count(&count) // SELECT COUNT(DISTINCT(`name`)) FROM `users` db.Table("deleted_users").Select("count(distinct(name))").Count(&count) // SELECT count(distinct(name)) FROM deleted_users // 分組計數 users := []User{ {Name: "name1"}, {Name: "name2"}, {Name: "name3"}, {Name: "name3"}, } DB.Model(&User{}).Group("name").Count(&count) count // => 3 ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看