使用 GORM连接数据库,并实现增删改查操作 |青训营

55 阅读4分钟

GORM是什么

GORM(Go Object Relational Mapping)是一个用于 Go 语言的开源 ORM(对象关系映射)库。它提供了一种简单且强大的方式来将 Go 结构体与数据库表进行映射,从而实现对数据库的操作。

GORM 提供了丰富的功能,包括:

    1. 创建、更新、删除和查询数据库记录。
    1. 支持事务操作,确保数据的一致性。
    1. 支持多种关系类型,如一对一、一对多、多对多等。
    1. 自动映射结构体和数据库表,无需手动编写 SQL 语句。
    1. 支持链式查询和条件构建,方便灵活地组装查询条件。
    1. 提供丰富的回调函数,允许在执行数据库操作前后执行自定义逻辑。
    1. 支持数据库迁移和数据模型变更的管理。
    1. 可以与各种主流的关系型数据库进行集成,如 MySQL、PostgreSQL、SQLite 等。

使用 GORM,可以更加方便地操作数据库,减少了手写 SQL 语句的繁琐过程,提高了开发效率。同时,GORM 还提供了良好的扩展性和可定制性,可以根据实际需求进行个性化配置和扩展。

快速入门

安装

go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

一般都会提示使用go installgo get失效,如果在配置go环境的时候没有在系统环境变量中添加GOPROXY,就去设置,变量值为https://goproxy.io,direct, 然后SET GO111MODULE=on ps:我在Goland的Terminal中使用上述安装命令成功。

连接过程中的问题

gorm下载 go mod

进行连接以及创建数据

go mod

在连接数据库之前,要对我们的项目进行初始化。 1.在项目Terminal中初始化一个module,go mod init xxx(xxx是你自定义的名称) 2.项目目录中就会出现这个mod文件,接下来应该是下载modules到本地go mod download(但这一步也常常出现问题,我就选择直接在根目录下增加go.mod,然后将初始化的xxx.mod内容复制进去)

连接

初始化后就可以进行连接 使用

type Product struct {
    ...
}
db.AutoMigrate(&Product{})

进行建表
或者在mysql workbench进行创建相应表

package main

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

type Product struct {
	ID    uint
	Code  string
	Price uint
}

func main() {
	db, err := gorm.Open(
		mysql.Open("username:psw@tcp(IP:port)/databasename?charset=utf8mb4&parseTime=True&loc=Local"),
		&gorm.Config{})
	if err != nil {
		panic("failed to connect")
	}

	u1 := Product{1, "D23", 100}
	db.Create(&u1)

}

type Product struct {}是使用gorm.Model结构体嵌套
需要注意的是

  • username:数据库用户名
  • psw:数据库连接密码
  • IP:数据库的IP
  • port:数据库端口
  • databasename:数据库名称
    以上需要根据自己的情况进行设定

上述代码在连接数据库的同时创建了第一条数据 其结果为

image.png

以及

image.png 可以看到我们创建的数据已经插入表中


创建多条数据:

func main() {
    ...
    //1
    pros := []*Product{{ID: 4}, {ID: 5}}
    res := db.Create(pros)
    //2
    u2 := Product{6, "A35", 600}
    u3 := Product{7, "B12", 100}
    db.Create(&u2)
    db.Create(&u3)
}

运行1后结果为:

image.png

image.png

运行2后的结果

image.png

1和2均为创建数据的代码,结果也可以从结果图中清楚看到

进行查询:


//查询第一条数据
func main() {
	...
	u := new(Product)
	db.First(u)
	fmt.Printf("%#v\n", u)
   或者 //u :=&Product{}
       //db.First(u)
       //fmt.Printf("%#v\n",u)
}

结果是:
main.Product{ID:0x1, Code:"D23", Price:0x64}
可以看到有两个数据格式不对:GORM 框架默认使用 uint 类型的整数字段作为自增主键,并且在查询结果时,会将其转换为指向对应实体的指针类型。所以,无论你如何修改打印代码,GORM 都会以十六进制格式输出实体的 IDPrice 值。

查询其他与多条数据:

func main() {
	...
	pds := make([]*Product, 0)
	result := db.Where("ID < n").Find(&pds)
        fmt.Println(result.RowsAffected)//返回找到的记录数	
}

这样我们可以查询到ID值小于n范围内的所有记录并进行打印到的记录数 如果想要打印结果,可以进行适当修改对fmt的调用。

修改数据

原本数据:

image.png

func main() {
    ...
    //更新指定字段数据
    //1
    db.Model(&Product{ID: 5}).Updates(Product{Code: "R19", Price: 900})
    //2
    db.Model(&Product{ID: 4}).Select("Code").Updates(map[string]interface{}{"Code": "E90", "Price": 900})
}

结果是

image.png

可以注意到2语句只更新了Code的值,而Price值保持不变,这是因为在 GORM 中,使用 Select() 方法会限制更新操作只针对指定的字段,其他未指定的字段将不会被更新。这里Select指定的是Code,所以只会更新Code字段的数据

db.Model(&Product{ID:4}).Updates(map[string]interface{}{"Code":"E90","Price":900}) 舍弃Select可以做到更新多字段

如果是db.Model(&Product{9}).Where("Price<?",10).Update("Code", "E90")会报错too few values in struct literal of type Product

删除数据

func main() {
	//物理删除
	db.Delete(&Product{}, 2)      //1     
	db.Delete(&Product{}, []int{4, 5}) //2
	db.Where("ID LIKE ?","%7%").Delete(Product{}) //3
	//软删除
	//删除一条
	u :=Product{ID:1}
	db.Delete(&u)
	//批量删除
	db.Where("ID IN ?",[]int{6,7,8}).Delete(&Product{})
	
}

1.delete from Products where ID=2
2.delete from products where ID in (4,5),删除 ID 为 4 或 5 的记录
3.delete from products where id like "%7%",根据条件删除 ID 含有 7 的记录

物理删除和软删除

在 GORM 中,物理删除和软删除是两种不同的删除策略,它们具有以下区别:

    1. 物理删除:物理删除是直接从数据库中永久删除数据记录的操作。当您使用 db.Delete() 方法执行物理删除时,相应的数据记录将被立即从数据库中删除,无法恢复。物理删除可以彻底清除不再需要的数据,但也可能导致数据的永久丢失。
    1. 软删除:软删除是一种将数据记录标记为已删除但保留在数据库中的操作。当您使用 GORM 提供的软删除功能时,实际上是更新了一个特定的字段来表示该记录已被删除。通常会使用一个名为 deleted_at 的时间戳字段来标记删除的记录。软删除允许您在需要时轻松恢复或查看已删除的数据记录。
    • 通过在gorm.Model模型中添加 DeletedAt 字段,GORM 将自动处理软删除的操作。当您调用 db.Delete() 方法时,它会将记录的 DeletedAt 字段设置为当前时间,表示该记录已被删除。您可以使用 db.Unscoped().Find() 方法来查询包括软删除记录的所有数据,并可以使用 db.Unscoped().Delete() 方法永久删除软删除的记录。