使用 GORM(Go 的 ORM 库)连接数据库,并实现增删

使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作

前言

本篇文章为面向用户层面的掌握 Go 语言基础以及了解 MySQL数据库,读完本篇文章,读者可以了解ORM框架的定义和熟悉使用GORM包进行基本的CRUD。

GORM

GORM是Go语言的一个ORM(Object Relational Mapping)库。它可以让我们通过Go来操作数据库中的数据。

ORM即对象关系映射,将数据库中的表转为程序中的实体对象(通过建立对象和关系数据之间的映射模型,可以将一个表对应一个实体类;将一条记录对应一个对象。)通过使用面向对象方式来操作数据库,可以简化开发,减少重复劳动。

特点

  • 数据操作功能:

    • 提供全功能的ORM(对象关系映射)功能,简化了数据库操作。
    • 支持多种关联关系,如Has One,Has Many,Belongs To,Many To Many,多态,单表继承。
    • 在Create、Save、Update和Delete等操作中,允许使用钩子方法来定制业务逻辑。
  • 高级查询与预加载:

    • 支持PreloadJoins的预加载,提高查询性能和效率。
  • 事务处理:

    • 提供事务管理功能,包括嵌套事务、Save Point和Rollback To Saved Point等。
    • 能够使用Context来管理事务,同时支持预编译模式和DryRun模式。
  • 灵活的数据操作:

    • 支持批量插入、FindInBatches、使用SQL表达式和Context Valuer进行CRUD操作。
  • 高级SQL功能:

    • 提供SQL构建器,支持Upsert操作、数据库锁、Optimizer/Index/Comment Hint等功能。
    • 支持命名参数和子查询,增强了查询灵活性。
  • 数据结构与迁移:

    • 支持复合主键、索引和约束。
    • 自动迁移功能能够简化数据库结构更新过程。
  • 定制化和扩展性:

    • 允许自定义Logger,适应不同的日志需求。
    • 提供灵活的插件API,如Database Resolver和Prometheus等,实现了多数据库、读写分离等功能。
  • 可靠性和开发友好:

    • 每个特性都经过充分测试,保证了框架的稳定性和质量。
    • 设计开发者友好,提供了简洁而强大的API接口,降低了使用难度。

CRUD

Create

新增一条记录

user := User{Name: "Jessica", Age: 24} // 创建一个user实体
db.Create(&user) // 创建一条记录
println(user.ID) // 记录新增后,会返回插入数据的主键并设置到user实体上
println(result.Error)       // 返回 error
println(result.RowsAffected) // 返回插入记录的条数

批量插入

var users = []User{{Name: "Alex", Age: 25}, {Name: "Bob", Age: 20}, {Name: "Candy", Age: 25}}
    db.Create(&users)
​
    for _, item := range users {
        println(item.ID)
    }

选定字段创建

用选定字段创建

user := User{Name: "aaa", Age:  20}
db.Select("Name", "Age").Create(&user)
//  INSERT INTO `users` (`created_at`,`updated_at`,`name`,`age`) VALUES ('2023-08-12 20:09:37.705','2023-08-12 20:09:37.705','samuelZhang1',20)

排除选定字段

user := User{Name: "aaa", Age: 20}
db.Omit("Age").Create(&user)
// INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`) VALUES ('2023-08-12 20:10:50.244','2023-08-12 20:10:50.244',NULL,'samuelZhang2')

Read

主键检索

// 根据主键获取第一条记录(主键升序)
user:=User{}
db.First(&user1)
// SELECT * FROM users ORDER BY id LIMIT 1;

// 根据主键获取最后一条记录(主键降序)
user:=User{}
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;

user:=User{}
result := db.First(&user)
println(result.RowsAffected) // 返回找到的记录数
println(result.Error)        // returns error

// 检查 ErrRecordNotFound 错误
errors.Is(result.Error, gorm.ErrRecordNotFound)

条件检索

// 获取第一条匹配的记录
db.Where("name = ?", "Alex").First(&user)
// SELECT * FROM users WHERE name = 'Alex' ORDER BY id LIMIT 1;
​
// IN
db.Where("name IN ?", []string{"Alex", "Samuel"}).Find(&users)
// SELECT * FROM users WHERE name IN ('Alex','Samuel');
​
// LIKE
db.Where("name LIKE ?", "%lex%").Find(&users)
// SELECT * FROM users WHERE name LIKE '%lex%';
​
// AND
db.Where("name = ? AND age >= ?", "Alex", "22").Find(&users)
// SELECT * FROM users WHERE name = 'Alex' 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';
​

Update

更新

单列

// 条件更新
db.Model(&User{}).Where("id = ?", 1).Update("name", "hello")
// UPDATE `users` SET `name`='hello',`updated_at`='2023-08-12 19:38:13.34' WHERE id = 1 AND `users`.`deleted_at` IS NULLuser := User{}
user.ID=1
db.Model(&user).Update("name", "hello")
// UPDATE `users` SET `name`='hello',`updated_at`='2023-08-12 19:38:13.50' WHERE id = 1 AND `users`.`deleted_at` IS NULL// 根据条件和 model 的值进行更新
user := User{}
user.ID=1
db.Model(&user).Where("age > ?",10 ).Update("name", "hello")
//  UPDATE `users` SET `name`='hello',`updated_at`='2023-08-12 19:41:08.037' WHERE age > 10 AND `users`.`deleted_at` IS NULL AND `id` = 1

多列

// 根据 `struct` 更新属性,只会更新非零值的字段
user := User{}
user.ID = 1
db.Model(&user).Updates(User{Name: "hello", Age: 0}) // Age将会被忽略
// UPDATE `users` SET `updated_at`='2023-08-12 19:45:15.084',`name`='hello' WHERE `users`.`deleted_at` IS NULL AND `id` = 1
​
// 根据 `map` 更新属性
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 0})
user := User{}
user.ID = 1
//  UPDATE `users` SET `age`=0,`name`='hello',`updated_at`='2023-08-12 20:00:13.544' WHERE `users`.`deleted_at` IS NULL AND `id` = 1

Delete

物理删除

// User表结构
type User struct {
    Name string
    Age  int
}
​
// 根据整形主键的删除
db.Delete(&User{}, 10)
// DELETE from `users` where `users`.`id` = 10;
​
// 根据额外条件的删除 (下面的例子将会批量删除)
db.Where("name = ?", "Alex").Delete(&User{},[]int{1,2,3})
// DELETE from `users`WHERE name = 'Alex' AND `users`.`id` IN (1,2,3);
​

软删除

// User表结构
type User struct {
    gorm.Model
    Name string
    Age  int
}
​
// 根据整形主键的删除
db.Delete(&User{}, 10)
// UPDATE `users` SET `deleted_at`='2023-08-13 15:04:13.696' WHERE `users`.`id` = 10 AND `users`.`deleted_at` IS NULL// 根据额外条件的删除 (下面的例子将会批量删除)
db.Where("name = ?", "Alex").Delete(&User{},[]int{1,2,3})
// UPDATE `users` SET `deleted_at`='2023-08-13 15:07:52.874' WHERE name = 'Alex' AND `users`.`id` IN (1,2,3) AND `users`.`deleted_at` IS NULL

总结

在使用GORM进行数据库操作时,需要按照以下步骤进行,以确保逻辑的清晰性和正确性。

  1. 导入包和驱动:首先,要导入GORM核心包以及所需的数据库驱动包。
  2. 选择和排除字段:在使用数据库操作时,可以使用db.Selectdb.Omit来选择和排除字段。但要注意,要确保字段是否允许为NULL。
  3. 查询或更新零值:如果需要查询或更新零值(如0、''、false),应使用WhereUpdate方法来构建查询条件。可以使用map[string]interface{}或SQL字符串来定义条件。
  4. 创建数据:使用db.Create来创建新的数据条目。如果要创建多条数据,可以使用切片。
  5. 查询数据:使用db.Find进行数据查找。可以通过使用WhereOr条件语句来构建查询条件,同时可以手动添加limit来限制返回的结果数量。
  6. 更新数据:使用db.Update进行数据更新。可以使用db.Model(User{}).Update来更新单列,或者使用db.Model(User{}).Updates来更新多列。也可以使用SQL表达式作为更新的值。
  7. 删除数据:使用db.Delete进行数据删除操作。如果Model中不包含gorm.deletedat字段,则会进行物理删除;如果包含该字段,则会进行逻辑删除(软删除)。
  8. 软删除操作:使用db.Unscoped()可以查找被标记为软删除的记录。如果需要对软删除的记录进行物理删除,可以使用db.Unscoped().Delete

总之,通过遵循以上步骤,可以更清晰地进行数据库操作,包括选择字段、查询、更新和删除操作,并能更好地处理软删除操作。同时,要注意处理异常情况,确保操作的稳定性和可靠性。

全部评论

相关推荐

05-12 11:09
已编辑
门头沟学院 后端
已注销:没必要放这么多专业技能的描述。这些应该是默认已会的,写这么多行感觉在凑内容。项目这块感觉再包装包装吧,换个名字,虽然大家的项目基本都是网上套壳的,但是你这也太明显了。放一个业务项目,再放一个技术项目。技术项目,例如中间件的一些扩展和尝试。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务