Go使用GORM ORM套件做SELECT ... WHERE
依條件查詢的方式如下。
範例環境:
- Go 1.19
- GORM 2.0 (gorm.io/gorm v1.24.2)
- PostgreSQL 14
事前要求
參考「Golang GORM PostgreSQL基本設定」設定資料庫及安裝GORM套件。
範例
GORM使用gorm.DB.Find(dest interface{}, conds ...interface{})
做select query查詢。
第一個參數dest interface{}
為儲存查詢結果的model or model slice pointer物件;
第二個可變參數conds ...interface{}
為where條件與值。
Inline Conditions
使用gorm.DB.Find
設定查詢條件的方式稱為inline condition。
emp := Employee{}
db.Find(&emp, "name = ? AND age = ?", "john", 33) // SELECT * FROM employee WHERE name = 'john' AND age = 33;
Where Conditions
或可另外用gorm.DB.Where(query interface{}, args ...interface{})
設定查詢條件與值。
emp := Employee{}
db.Where("name = ? AND age = ?", "john", 33).Find(&emp) // SELECT * FROM employee WHERE name = 'john' AND age = 33;
Map Conditions
Where條件除了用字串及參數表示,也可用map替代稱為map conditions;map的key為查詢欄位,值為查詢欄位的值。這也適用於inline condition。
emp := Employee{}
// use map as where conditions
conditionMap := map[string]interface{}{
"name": "john",
}
db.Where(conditionMap).Find(&emp) // SELECT * FROM employee WHERE name = 'john';
Struct Conditions
Where條件也可用struct model替代稱為struct conditions;model的屬性為查詢欄位,值為查詢欄位的值。這也適用於inline condition。
emp := Employee{}
// use struct model as where conditions
conditionStruct := Employee{
Name: "john",
}
db.Where(conditionStruct).Find(&emp) // SELECT * FROM employee WHERE name = 'john';
Primary Key Condition
注意gorm.DB.Find
的回傳model中若primary key屬性有值,則除了原本的查詢條件還會加上primary key條件及排序。
emp := Employee{ID: 2} // model has primary key field value
db.Where("name = ?", "john").Find(&emp) // SELECT * FROM employee WHERE name = 'john' AND id = 2 ORDER BY id LIMIT 1;
Multiple Results
使用model slice接收多個查詢結果。
// select multiple results
var emps []Employee // use model slice for multiple results
db.Where("age > ?", 30).Find(&emps) // SELECT * FROM employee WHERE age > 30;
以下是where查詢的一些簡單範例。
main.go
package main
import (
"fmt"
"time"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
type Employee struct {
ID int64 // primary key, column name is `id`
Name string // column name is `name`
Age int // column name is `age`
CreatedAt time.Time // column name is `created_at`
}
const (...)
func getGormDB() *gorm.DB {...}
func main() {
db := getGormDB()
// select with where conidtions
emp := Employee{} // use struct model for single result
db.Where("name = ?", "john").Find(&emp) // SELECT * FROM employee WHERE name = 'john';
fmt.Println(emp)
db.Where("name = ? AND age = ?", "john", 33).Find(&emp) // SELECT * FROM employee WHERE name = 'john' AND age = 33;
fmt.Println(emp) // {1 john 33 2022-11-29 18:44:54.114161 +0000 UTC}
// use map as where conditions
conditionMap := map[string]interface{}{
"name": "john",
}
db.Where(conditionMap).Find(&emp) // SELECT * FROM employee WHERE name = 'john';
fmt.Println(emp) // {1 john 33 2022-11-29 18:44:54.114161 +0000 UTC}
// use struct model as where conditions
conditionStruct := Employee{
Name: "john",
}
db.Where(conditionStruct).Find(&emp) // SELECT * FROM employee WHERE name = 'john';
fmt.Println(emp) // {1 john 33 2022-11-29 18:44:54.114161 +0000 UTC}
// inline select with where conidtion
db.Find(&emp, "name = ?", "john") // SELECT * FROM employee WHERE name = 'john';
fmt.Println(emp) // {1 john 33 2022-11-29 18:44:54.114161 +0000 UTC}
db.Find(&emp, "name = ? AND age = ?", "john", 33) // SELECT * FROM employee WHERE name = 'john' AND age = 33;
fmt.Println(emp) // {1 john 33 2022-11-29 18:44:54.114161 +0000 UTC}
// inline select with map conditions
db.Find(&emp, conditionMap) // SELECT * FROM employee WHERE name = 'john';
fmt.Println(emp) // {1 john 33 2022-11-29 18:44:54.114161 +0000 UTC}
// inline select with struct model conditions
db.Find(&emp, conditionStruct) // SELECT * FROM employee WHERE name = 'john';
fmt.Println(emp) // {1 john 33 2022-11-29 18:44:54.114161 +0000 UTC}
// select with where condition and primary key
emp = Employee{ID: 2} // model has primary key field value
db.Where("name = ?", "john").Find(&emp) // SELECT * FROM employee WHERE name = 'john' AND id = 2 ORDER BY id LIMIT 1;
fmt.Println(emp) // {1 john 33 2022-11-29 18:44:54.114161 +0000 UTC}
// select multiple results
var emps []Employee // use model slice for multiple results
db.Where("age > ?", 30).Find(&emps) // SELECT * FROM employee WHERE age > 30;
fmt.Println(emps) // [{3 tony 45 2022-12-22 22:05:09.83327 +0000 UTC} {1 john 33 2022-12-22 21:56:37.061419 +0000 UTC}]
// select with where between
db.Where("age BETWEEN ? AND ? ", 18, 30).Find(&emps) // SELECT * FROM employee WHERE age BETWEEN 18 AND 30;
fmt.Println(emps) // [{2 mary 28 2022-12-22 21:56:37.061419 +0000 UTC}]
// select with where order by
db.Where("age > ?", 30).Order("age asc").Find(&emps) // SELECT * FROM employee WHERE age > 30 ORDERY BY age DESC;
fmt.Println(emps) // [{1 john 33 2022-12-22 21:56:37.061419 +0000 UTC} {3 tony 45 2022-12-22 22:05:09.83327 +0000 UTC}]
}
沒有留言:
張貼留言