这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记
1.连接数据库
db, err := gorm.Open("mysql","root:123456@(127.0.0.1:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db1:数据库名字
2.简单操作
先创建一个字段,添加到数据库中
type UserInfo struct {
Id int
Name string
Gender string
Hobby string
}
//迁移,将表迁移到数据库中
db.AutoMigrate(&UserInfo{})
u1 := UserInfo{1, "王二麻子", "男", "编程"}
//添加数据,创建记录,给指针是为了减小内存
db.Create(&u1)
查找数据
//查找数据
var u2 UserInfo
var u3 UserInfo
db.First(&u2, 1)//按照主键查找
db.First(&u3, "name = ?", "王二麻子")//按照name字段查找为李杰的数据
更新数据,删除数据
// Update
db.Model(&u2).Update("hobby", "篮球")
// Delete
db.Delete(&u2, 1)//主键
1.单个查询
GORM 提供了 First、Take、Last 方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1 条件,且没有找到记录时,它会返回 ErrRecordNotFound 错误
// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;
// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;
// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
result := db.First(&user)
result.RowsAffected // 返回找到的记录数
result.Error // returns error
// 检查 ErrRecordNotFound 错误
errors.Is(result.Error, gorm.ErrRecordNotFound)
First、Last 方法会根据主键查找到第一个、最后一个记录, 它仅在通过 struct 或提供 model 值进行查询时才起作用。 如果 model 类型没有定义主键,则按第一个字段排序,例如:
var user User
// 可以
db.First(&user)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1
// 可以
result := map[string]interface{}{}
db.Model(&User{}).First(&result)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1
// 不行
result := map[string]interface{}{}
db.Table("users").First(&result)
// 但可以配合 Take 使用
result := map[string]interface{}{}
db.Table("users").Take(&result)
// 根据第一个字段排序
type Language struct {
Code string
Name string
}
db.First(&Language{})
// SELECT * FROM `languages` ORDER BY `languages`.`code` LIMIT 1
2.根据主键查询
db.First(&user, 10)
// SELECT * FROM users WHERE id = 10;
db.First(&user, "name = ?","哈哈")
// SELECT * FROM users WHERE name = 哈哈;
//注意,这个users是一个切片类型的
db.Find(&users, []int{1,2,3})
// SELECT * FROM users WHERE id IN (1,2,3);
3.查询所有对象
// 获取全部记录
//注意,这个users是一个切边类型的
result := db.Find(&users)
// SELECT * FROM users;
result.RowsAffected // 返回找到的记录数,相当于 `len(users)`
result.Error // returns error
4.条件查询
1.string条件
利用数据库查询中where的方法
// 获取第一条匹配的记录
db.Where("name = ?", "jinzhu").First(&user)
// SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;
// 获取全部匹配的记录
//注意,这个users是一个切边类型的
db.Where("name <> ?", "jinzhu").Find(&users)
// SELECT * FROM users WHERE name <> 'jinzhu';
// IN
//注意,这个users是一个切边类型的
db.Where("name IN ?", []string{"jinzhu", "jinzhu 2"}).Find(&users)
// SELECT * FROM users WHERE name IN ('jinzhu','jinzhu 2');
// LIKE
//注意,这个users是一个切边类型的
db.Where("name LIKE ?", "%jin%").Find(&users)
// SELECT * FROM users WHERE name LIKE '%jin%';
2.Struct & Map 条件
// 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
//注意,这个users是一个切边类型的
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;
// 主键切片条件
//注意,这个users是一个切边类型的
db.Where([]int64{20, 21, 22}).Find(&users)
// SELECT * FROM users WHERE id IN (20, 21, 22);
当使用结构作为条件查询时,GORM 只会查询非零值字段。这意味着如果您的字段值为 0、''、false 或其他 零值,该字段不会被用于构建查询条件,而map没有限制,当零值字段时,可以用map查询
3.内联条件
与where相似
// SELECT * FROM users WHERE id = 23;
// 根据主键获取记录,如果是非整型主键
db.First(&user, "id = ?", "string_primary_key")
// SELECT * FROM users WHERE id = 'string_primary_key';
// Plain SQL
//注意,这个users是一个切边类型的
db.Find(&user, "name = ?", "jinzhu")
// SELECT * FROM users WHERE name = "jinzhu";
4.Not条件
与where相似
db.Not("name = ?", "jinzhu").First(&user)
// SELECT * FROM users WHERE NOT name = "jinzhu" ORDER BY id LIMIT 1;
// Not In
db.Not(map[string]interface{}{"name": []string{"jinzhu", "jinzhu 2"}}).Find(&users)
// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");
5.Or条件
db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)
// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';
// Struct
db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2", Age: 18}).Find(&users)
// SELECT * FROM users WHERE name = 'jinzhu' OR (name = 'jinzhu 2' AND age = 18);
// Map
db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name": "jinzhu 2", "age": 18}).Find(&users)
// SELECT * FROM users WHERE name = 'jinzhu' OR (name = 'jinzhu 2' AND age = 18);
5.选择特定字段
选择您想从数据库中检索的字段,默认情况下会选择全部字段
db.Select("name", "age").Find(&users)
// SELECT name, age FROM users;
db.Select([]string{"name", "age"}).Find(&users)
// SELECT name, age FROM users;
1.智能选择字段
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
2.子查询
子查询可以嵌套在查询中,GORM 允许在使用 *gorm.DB 对象作为参数时生成子查询
db.Where("amount > (?)", db.Table("orders").Select("AVG(amount)")).Find(&orders)
// SELECT * FROM "orders" WHERE amount > (SELECT AVG(amount) FROM "orders");