Go的gorm简单入门(连接与查询)|青训营笔记

144 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第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 提供了 FirstTakeLast 方法,以便从数据库中检索单个对象。当查询数据库时它添加了 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)

FirstLast 方法会根据主键查找到第一个、最后一个记录, 它仅在通过 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");