GORM:从了解安装到数据库增删改查的操作实现 | 青训营

什么是GORM?

GORM 是 Go 语言中的一个强大的对象关系映射(ORM)库,它提供了一种简单且优雅的方式来进行数据库操作。ORM 是一种编程技术,它将数据库表与程序中的对象进行映射,使得开发者可以使用面向对象的方式进行数据库的增删改查操作,而无需直接编写 SQL 语句。

GORM 提供了许多功能和特性,包括:

  1. 模型定义:GORM 允许开发者通过定义结构体来表示数据库表,并可以通过在结构体中进行标记(tagging)来指定字段名称、数据类型、约束条件等。
  2. 数据库迁移:GORM 支持自动化数据库迁移,即根据模型定义自动生成数据库表,以及根据模型的更改自动更新数据库表结构。
  3. CRUD 操作:GORM 提供了简单易用的 API,可以进行常见的数据库操作,如创建(Create)、读取(Retrieve/Query)、更新(Update)、删除(Delete)等。
  4. 查询构建器:GORM 提供了强大的查询构建器,可以通过链式调用的方式构建复杂的查询语句,并支持条件筛选、排序、分页等功能。
  5. 关联关系:GORM 支持定义和处理数据库表之间的关联关系,如一对一、一对多、多对多等关系,在查询时可以方便地进行关联数据的加载。
  6. 事务支持:GORM 提供了事务管理的功能,可以确保一组数据库操作要么全部成功要么全部失败,从而保持数据的一致性。

在其他语言中有类似的存在吗?

是的,其他编程语言中也有类似于 GORM 的 ORM 库,用于简化数据库操作,提高开发效率。下面列举几种常见的 ORM 库:

  1. SQLAlchemy(Python):SQLAlchemy 是 Python 中的一个流行的 ORM 库,支持多种数据库后端,包括 PostgreSQL、MySQL、SQLite 等。它提供了灵活的对象关系映射和强大的查询构建功能。
  2. Hibernate(Java):Hibernate 是 Java 中最受欢迎的 ORM 框架之一,它提供了全面的数据库操作解决方案。Hibernate 支持各种关系型数据库,并提供了丰富的特性,如数据缓存、事务管理、查询语言等。
  3. Entity Framework(C#):Entity Framework 是 C# 中的官方 ORM 框架,它提供了对多种数据库的支持,如 SQL Server、MySQL、Oracle 等。通过 Entity Framework,开发者可以使用 LINQ 查询语言进行数据库操作。
  4. Django ORM(Python):Django ORM 是 Django Web 框架默认集成的 ORM 工具,它提供了便捷的数据库操作方式,并支持多种数据库后端。Django ORM 具有清晰的API设计和强大的查询功能。
  5. ActiveRecord(Ruby):ActiveRecord 是 Ruby on Rails 框架中的默认 ORM 层,它通过将数据库表映射到 Ruby 类来实现数据库操作。ActiveRecord 提供了丰富的方法和约定,简化了数据库操作的编写。

1. 引入 GORM

首先,我们需要引入 GORM 包,可以通过以下命令来获取:

shell 复制代码
go get gorm.io/gorm
go get gorm.io/driver/mysql      

可能遇到的问题:

  1. 在命令行输入上述指令( 或代理版本:go get github.com/go-sql-driver/mysql )可能出现下载不成功的情况,这时候需要我们更改Go env中的代理设置可解决问题

在命令行中输入:

go env -w GOPROXY=goproxy.cn,direct

  1. 成功下载了MySQL数据库驱动程序,但导入时提示找不到依赖包 原因分析 可能是因为包管理Go Modules方式设置错误导致,默认情况下,依赖包会下载到GOPATH\src\github.com\路径下,如果之前设置了go env -w GO111MODULE=on,则会下载到GOPATH\pkg\mod\github.com\路径下,导致招不到依赖包。

解决办法:

ini 复制代码
将下载好的依赖包拷贝到GOPATH\src\路径下
设置go env -w GO111MODULE=off,重新下载

2. 连接数据库

在代码中,我们首先需要配置数据库连接信息并建立连接。这里以 MySQL 数据库为例:

go 复制代码
package main

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

func main() {
    dsn := "user:password@tcp(localhost:3306)/database?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        fmt.Println("无法连接到数据库:", err)
        return
	}
    sqlDB, err := db.DB()  
    defer sqlDB.Close()
	// 后续数据库操作...
}

请根据实际情况修改 dsn 变量中的数据库连接信息,包括用户名、密码、主机地址、端口号和数据库名称等。

dsn是什么?

DSN 是 "Data Source Name"(数据源名称)的缩写,它是一种用于标识和定位数据库或其他数据源的字符串格式。DSN 包含了连接数据库所需的信息,如数据库类型、主机名、端口、数据库名称、认证凭据等。

不同的数据库和应用程序可能会使用不同的 DSN 格式。以下是一些常见的 DSN 示例:

  1. MySQL DSN 示例:

    text 复制代码
    mysql://username:password@hostname:port/database
  2. PostgreSQL DSN 示例:

    text 复制代码
    postgresql://username:password@hostname:port/database
  3. SQL Server DSN 示例:

    text 复制代码
    sqlserver://username:password@hostname:port;database=database
  4. SQLite DSN 示例:

    text 复制代码
    sqlite:///path/to/database.db

在使用某个编程语言或框架连接数据库时,通常需要提供正确的 DSN 来指定数据库的位置和其他连接参数。具体的 DSN 格式和要求,请参考对应数据库或框架的文档或手册,以确保提供正确的连接信息。

3. 定义模型结构

在 GORM 中,连接成功后,我们需要定义数据库表对应的模型结构体。以用户表(users)为例:

go 复制代码
type User struct {  
    ID uint  
    Name string  
    Age int  
}

上述代码定义了一个 User 结构体,它包含了 Id Name Age 三个字段,分别表示用户的id,姓名,年龄(在这里我们随意举例做个示例)

4. 创建表

在连接到数据库后,我们可以使用 GORM 提供的自动迁移功能来创建表。只需调用 AutoMigrate 方法,并将模型作为参数传入即可:

go 复制代码
db.AutoMigrate(&User{})

上述代码将会在数据库中创建一个名为 users 的表,并自动添加与 User 结构体对应的字段。 当然,也可以在自己写一个sql执行,比如:

sql 复制代码
create TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255),
  age INT
);

5. 数据操作

接下来,我们可以使用 GORM 提供的方法来进行数据操作,例如插入、查询、更新和删除(增删改查)等。

插入数据

go 复制代码
user := User{  Name: "JohnWick",  Age: 25, }
db.Create(&user)

上述代码创建了一个名为 JohnWick 的用户,并将其插入到数据库中。

查询数据

go 复制代码
var users []User
db.Find(&users)

上述代码通过使用 Find 方法查询数据库中的所有用户,并将结果存储在 users 变量中。

更新数据

go 复制代码
var user User
db.First(&user)
user.age = 99
db.Save(&user)

上述代码首先查询数据库中的第一个用户,并将其年龄修改为 99,然后通过调用 Save 方法保存更改。

或者:

go 复制代码
var retrievedUser User

result = db.Model(&retrievedUser).Update("Age", 30)  
if result.Error != nil {  
panic(result.Error)  
}

删除数据

go 复制代码
db.Delete(&user)

可用上述代码删除数据库中的指定用户。

题外话: 重置数据库的自增计数器

当我写完一套代码进行 增 查 改 删 时,我发现即使数据库的最后状态是空的,但是每次执行代码,id都会自增1,我就在想怎么能够重置自增计数器,最后得出以下代码,单纯的delete是无法达到目的的,我们需要alter table

go 复制代码
err = db.Transaction(func(tx *gorm.DB) error {  
if err := tx.Session(&gorm.Session{AllowGlobalUpdate: true}).Model(&User{}).Delete(&User{}).Error; err != nil {  
return err  
}  
if err := tx.Exec("ALTER TABLE users AUTO_INCREMENT = 1").Error; err != nil {  
return err  
}  
return nil  
})  
if err != nil {  
fmt.Println("重置数据表时出错:", err)  
return  
}  
  
fmt.Println("数据表已清空并自增计数器已重置")

继续题外话

问:如何清除MySQL自增ID?

答: MySQL的自增ID是一种非常重要的特性, 它可以自动为每条记录分配一个唯一 的ID, 以便于在数据库中进行操作。但是,有时候我们需要清除自增ID,比如在测试环境中重置数据或者在生产环境中删除一些记录。 下面我们将介绍三种清除MySQL自增ID的方法。

方法一:使用TRUNCATE TABLE语句

TRUNCATE TABLE语可以快速清空-张表的所有数据, 并重置自增ID。使用该语句时需要注意以下几点:

  1. TRUNCATE TABLE语询会删除表中的所有数据,因此务必备份数据。

  2. TRUNCATE TABLE语不支持WHERE子句,它会一次性删除整张表的数据。

  3. TRUNCATE TABLE语句会重置自增ID,下一次插入数据时自增ID会从1开始计数。

下面是一个示例:

方法二:使用ALTER TABLE语句

ALTER TABLE语句可以修改表的结构,包括删除表中的列、添加新的列、修改列的数据类型等。使用该语句时需要注意以下凡点:

  1. ALTER TABLE语句可以删除表中的列,这样也可以重置自增ID。

  2. ALTER TABLE语句可以修改表的结构,因此请务必备份数据。

  3. ALTER TABLE语句会重置自增ID,下一-次插入数据时自增ID会从1开始计数。

下面是一个示例:

amename;

方法三:使用DELETE语句

DELETE语可以删除表中的数据,但是它不会重置自增ID。使用该语句时需要注意以下凡点:

  1. DELETE语句可以删除表中的数据,但是不会删除表中的结构。

  2. DELETE语句不会重置自增ID,下一 次插入数据时自增ID会从上一次的最大值加1开始计数。

6.关闭数据库

当所有操作完成后,我们需要关闭数据库连接以释放资源:

go 复制代码
db.Close()

或者:

go 复制代码
db, err := gorm.Open("mysql", "user:password@tcp(localhost:3306)/database")
if err != nil {
    // 处理连接错误
    return err
}

defer db.Close()

// 执行数据库操作
// ...

使用 defer 关键字可以避免忘记在适当的位置手动关闭数据库连接,提高代码的可读性和可维护性。同时,这样的做法也可以在函数发生异常时保证数据库连接的关闭,从而避免资源泄漏。

总之,使用 defer 关闭数据库连接是一个良好的编程习惯,建议在适当的位置使用 defer 来确保数据库连接的关闭。这样可以提高代码的可靠性和可维护性。

结语

本文的内容大概就是这么些了QWQ 仅代表个人见解,如有误或遗漏望指正

相关推荐
千慌百风定乾坤4 小时前
Go 语言入门指南:基础语法和常用特性解析(下) | 豆包MarsCode AI刷题
青训营笔记
FOFO4 小时前
青训营笔记 | HTML语义化的案例分析: 粗略地手绘分析juejin.cn首页 | 豆包MarsCode AI 刷题
青训营笔记
滑滑滑2 天前
后端实践-优化一个已有的 Go 程序提高其性能 | 豆包MarsCode AI刷题
青训营笔记
柠檬柠檬2 天前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记
用户967136399652 天前
计算最小步长丨豆包MarsCodeAI刷题
青训营笔记
用户52975799354723 天前
字节跳动青训营刷题笔记2| 豆包MarsCode AI刷题
青训营笔记
clearcold3 天前
浅谈对LangChain中Model I/O的见解 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵4 天前
【字节青训营】 Go 进阶语言:并发概述、Goroutine、Channel、协程池 | 豆包MarsCode AI刷题
青训营笔记
用户336901104444 天前
数字分组求和题解 | 豆包MarsCode AI刷题
青训营笔记
dnxb1234 天前
GO语言工程实践课后作业:实现思路、代码以及路径记录 | 豆包MarsCode AI刷题
青训营笔记