模型是 Go 中的结构体,字段类型可以是基础 Go 类型、指针或者这些类型的别名。也支持自定义类型,只要实现了来自 database/sql 包的 Scanner 和 Valuer 接口。指针的作用是允许 nili 值,与数据库中的 null 对应。
模型定义如下:
1 2 3 4 5 6 7 8 9 10 11
type User struct { ID uint// Standard field for the primary key Name string// A regular string field Email *string// A pointer to a string, allowing for null values Age uint8// An unsigned 8-bit integer Birthday *time.Time // A pointer to time.Time, can be null MemberNumber sql.NullString // Uses sql.NullString to handle nullable strings ActivatedAt sql.NullTime // Uses sql.NullTime for nullable time fields CreatedAt time.Time // Automatically managed by GORM for creation time UpdatedAt time.Time // Automatically managed by GORM for update time }
// gorm.Model 的定义 type Model struct { ID uint`gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"`// index tag 用于根据参数创建索引 }
type User struct { gorm.Model // 嵌入匿名字段 Name string } // 等价于 type User struct { ID uint`gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` Name string }
var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}} result := db.Create(users) // 传递切片以插入多行数据 for _, user := range users { user.ID // 1,2,3 }
// Get first matched record db.Where("name = ?", "jinzhu").First(&user) // SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;
// Get all matched records db.Where("name <> ?", "jinzhu").Find(&users) // SELECT * FROM users WHERE name <> 'jinzhu';
// IN db.Where("name IN ?", []string{"jinzhu", "jinzhu 2"}).Find(&users) // SELECT * FROM users WHERE name IN ('jinzhu','jinzhu 2');
// LIKE db.Where("name LIKE ?", "%jin%").Find(&users) // SELECT * FROM users WHERE name LIKE '%jin%';
// AND db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users) // SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22;
// Time db.Where("updated_at > ?", lastWeek).Find(&users) // SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00';
// BETWEEN db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users) // SELECT * FROM users WHERE created_at BETWEEN '2000-01-01 00:00:00' AND '2000-01-08 00:00:00';
// Struct db.Where(&User{Name: "jinzhu", Age: 20}).First(&user) // SELECT * FROM users WHERE name = "jinzhu" AND age = 20 ORDER BY id LIMIT 1;
// Map db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users) // SELECT * FROM users WHERE name = "jinzhu" AND age = 20;
// Slice of primary keys db.Where([]int64{20, 21, 22}).Find(&users) // SELECT * FROM users WHERE id IN (20, 21, 22);
内联条件
First 中可以类似 Where,进行条件内联。
1 2 3 4 5 6
// Get by primary key if it were a non-integer type db.First(&user, "id = ?", "string_primary_key") // SELECT * FROM users WHERE id = 'string_primary_key';
Save 是一个组合函数。 如果保存值不包含主键,它将执行 Create,否则它将执行 Update (包含所有字段)。
单列
可以根据条件、model、条件 & model 完成指定列的参数更新。当使用 Update 更新单列时,需要有一些条件,否则将会引起 ErrMissingWhereClause 错误,详见阻止全局更新 。 当使用 Model 方法,并且它有主键值时,主键将会被用于构建条件,例如:
1 2 3 4 5 6 7 8 9 10 11 12
// 根据条件更新 db.Model(&User{}).Where("active = ?", true).Update("name", "hello") // UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true;
// User 的 ID 是 `111` db.Model(&user).Update("name", "hello") // UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
// 根据条件和 model 的值进行更新 db.Model(&user).Where("active = ?", true).Update("name", "hello") // UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
多列
类似地,支持使用结构体和 map 更新,struct 只更新非零值。
1 2 3 4 5 6 7 8
// 根据 `struct` 更新属性,只会更新非零值的字段 db.Model(&user).Updates(User{Name: "hello", Age: 18, Active: false}) // UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;
// user's ID is `111` db.Delete(&user) // UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;
// Batch Delete db.Where("age = ?", 20).Delete(&User{}) // UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;
// Soft deleted records will be ignored when querying db.Where("age = 20").Find(&user) // SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
可以使用 Unscoped 来查询到被软删除的记录,或者永久删除匹配的记录
1 2 3 4 5 6 7
// 不过滤被软删除的记录 db.Unscoped().Where("age = 20").Find(&users) // SELECT * FROM users WHERE age = 20; // 永久删除 db.Unscoped().Delete(&order) // DELETE FROM orders WHERE id=10;