Gorm框架增删改查| 青训营

43 阅读4分钟

CRUD

CRUD通常指数据库的增删改查操作。 推荐大家去官网,有更加详细的示例。 首先,要导入必要的包,并初始化gorm

import (
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/mysql"
)

func main() {
  db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
  defer db.Close()
  
}

1 新增记录

//先定义模型对应数据库的表,也可以通过tag设置字段的默认值
type User struct{
    ID int64
    Name string `gorm:"default:'小明'"`
    Age int64

}
//初始化数据并添加
user:=User{Name:"小明",Age:18}
//使用NewRecord()查询主键是否存在
db.NewRecord(user) //如果存在的话会返回false,不存在返回true
db.Create(&user)

通过tag定义字段的默认值,在创建记录时候生成的 SQL 语句会排除没有值或值为 零值 的字段。 在将记录插入到数据库后,Gorm会从数据库加载那些字段的默认值。

可以使用指针的方式解决这个问题

user:=User{Name: new(string),Age:18}
//此时数据库就会保存这个零值,不会设置为默认值

2 查询

2.1一般查询

// 根据主键查询第一条记录
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;

// 查询所有的记录
db.Find(&users)
//// SELECT * FROM users;

// 查询指定的某条记录(仅当主键为整型时可用)
db.First(&user, 10)
//// SELECT * FROM users WHERE id = 10;

2.2条件查询

Where条件


db.Where("name=?","小明").First(&user)
//select * from users where name = '小明' limit 1;

db.Where("name=?","小明").Find(&user)
//select * from users where name = '小明' ;

db.Where("name<>?","小明").Find(&user)
//select * from users where name != '小明' ;

db.Where("name in (?)",[]sting{"小明","小红"}).Find(&user)
//select * from users where name in ('小明','小红') ;

db.Where("name like ?","小%").Find(&user)
//select * from users where name like '小%' ;

db.Where("updated_at > ?", lastWeek).Find(&users)
//SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00';

//************还可以在里面使用结构体或者map来查询
db.Where(&User{Name:"小明",Age:18}).First(&user)
//select * from users where name = '小明' and age = 18 limit 1;

db.Where(map[string]interface{}{"name":"小明","age":18}).First(&user)
//select * from users where name = '小明' and age = 18 limit 1;

当通过结构体进行查询时,GORM将会只通过非零值字段查询,这意味着如果你的字段值为0''false或者其他零值时,将不会被用于构建查询条件 你也可以使用指针或者实现Scanner/Valuer接口来解决问题。

// 使用指针
type User struct {
  gorm.Model
  Name string
  Age  *int
}

// 使用 Scanner/Valuer
type User struct {
  gorm.Model
  Name string
  Age  sql.NullInt64  // sql.NullInt64 实现了 Scanner/Valuer 接口
}

Not条件查询和Where类似就不多展示。

Or条件

db.Where("name = ?", "admin").Or("name = ?", "小明").Find(&users)
//// SELECT * FROM users WHERE name = 'admin' OR name = '小明';

// Struct
db.Where("name = '小明'").Or(User{Name: "小红"}).Find(&users)
//// SELECT * FROM users WHERE name = '小明' OR name = '小红';

// Map
db.Where("name = '小明'").Or(map[string]interface{}{"name": "小红"}).Find(&users)
//// SELECT * FROM users WHERE name = '小明' OR name = '小红';

内联条件

db.First(&user,1)
//select * from users where id =1 limit 1;

db.First(&user,"id =? ","1")
//select * from users where id =1 limit 1;

添加额外操作

// 为查询 SQL 添加额外的 SQL 操作
db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)
//// SELECT * FROM users WHERE id = 10 FOR UPDATE;

2.3高级查询

子查询


db.Where("amount > ?", db.Table("orders").Select("AVG(amount)").Where("state = ?", "paid").SubQuery()).Find(&orders)
// SELECT * FROM "orders"  WHERE "orders"."deleted_at" IS NULL AND (amount > (SELECT AVG(amount) FROM "orders"  WHERE (state = 'paid')));

选择字段查询

db.Select("name",age).Find(&users)
//select name ,age from users;


db.Select([]string{"name", "age"}).Find(&users)
// SELECT name, age FROM users;

排序

db.Order("age" desc ,name").Find(&users)
// select * from users order by age desc,name;

数量和偏移

db.Limit(3).Find(&users)
// SELECT * FROM users LIMIT 3;

// -1 取消 Limit 条件
db.Limit(10).Find(&users1).Limit(-1).Find(&users2)
// SELECT * FROM users LIMIT 10; (users1)
// SELECT * FROM users; (users2)


db.Offset(3).Find(&users)
// SELECT * FROM users OFFSET 3;

// -1 取消 Offset 条件
db.Offset(10).Find(&users1).Offset(-1).Find(&users2)
// SELECT * FROM users OFFSET 10; (users1)
// SELECT * FROM users; (users2)

连接操作 joins

rows, err := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows()

gorm还支持链式编程,所以你可以把代码写成这样

tx :=db.Where("name =?","小明")
tx=tx.Where("age =?",18)

在调用立即执行方法之前不会生成语句。

立即调用方法: Create,First,Find,Sava,Delete...

更新

Save()默认会更新该对象的所有字段,即使你没有赋值。

db.First(&user)

user.Name = "小明"
user.Age = 18
db.Save(&user)

////  UPDATE `users` SET `name` = 'v', `age` = 18,  WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1

如果你希望更新指定的字段,可以使用update

// 更新单个属性,如果它有变化
db.Model(&user).Update("name", "hello")
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;

删除

删除记录时,请确保主键字段有值,GORM 会通过主键去删除记录,如果主键为空,GORM 会删除该 model 的所有记录。

// 删除现有记录
db.Delete(&email)
//// DELETE from emails where id=10;

// 为删除 SQL 添加额外的 SQL 操作
db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email)
//// DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN);

批量删除


db.where("name like ?","%白%").Delete(User{})