GORM实现数据库连接和增删改查|青训营

173 阅读4分钟

基本介绍

gorm能将数据库表中的数据映射到面向对象的模型中来简化了数据库操作。gorm支持多种常见的数据库系统,包括MySQL、SQLSever、PostgreSQL、SQLite。让操作者无需因为操作系统的不同来更改代码。

安装GORM库和MySQL驱动

首先,确保你已经安装了Go语言环境。然后,使用以下命令安装GORM库和MySQL驱动:

bashCopy codego get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

连接MySQL数据库

在你的Go项目中,创建一个文件(例如main.go)并导入所需的包:

goCopy codepackage main

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

func main() {
	dsn := "user:password@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal("无法连接数据库:", err)
	}
	
	// 在此之后,你可以使用db变量执行各种数据库操作
	defer db.Close() // 程序结束时关闭数据库连接
}

hostuserpasswordportdbname将MySQL数据库的实际信息替换掉。

定义模型

在GORM中,模型是与数据库表对应的结构体。创建一个User模型,用于进行增删改查操作:

goCopy codetype User struct {
	gorm.Model
	Name  string
	Email string
}

创建数据表

在入口函数中,使用AutoMigrate方法创建数据库表:

goCopy codefunc main() {
	// ... 连接数据库代码 ...

	// 创建数据表
	db.AutoMigrate(&User{})
}

查询

创建一个结构体和数据表字段对应

world中有三张表city、country和countrylanguage。这里以world中city表为例进行数据查询:

type City struct {
	ID          int    `gorm:"primaryKey"`
	Name        string `gorm:"not null;default:''"`
	CountryCode string `gorm:"column:CountryCode;not null;default:''"`
	District    string `gorm:"not null;default:''"`
	Population  int    `gorm:"not null;default:0"`
}
// 设置 `City` 的表名为 `city`
func (City) TableName() string {
	return "city"
}

注意,需要设置func (City) TableName(),否则查询时将报错Error 1146 (42S02): Table 'world.cities' doesn't exist。GORM默认将struct name转为snake_cases为表名,对于 struct City,其表名是cities约定俗成的。GORM默认struct字段名field name转为snake_case单数形式为表字段名。可以通过设置gorm:"column:..."来使用别的转换规则,上面例子中的CountryCode只需要使用gorm:"column:CountryCode"标签定义为CountryCode字段指定表字段名,其他使用默认值即可。

执行查询操作

多个结果,因为city为list可全部接收,如果city长度有限,则只接收有限个结果。

var city []City
db.Find(&city)

查询特定情况:主键检索。

db.Find(&city, 1) 
db.Find(&users,[]int{1,2,3})

查询特定情况:where case检索。

db.Find(&city, "CountryCode=? AND Population>?", "AFG", "150000") //通过find内联。
db.Where("CountryCode=? AND Population>?", "AFG", "150000").Find(&city)
db.Where(map[string]interface{}{"CountryCode": "AFG"}).Find(&city)
db.Where(&City{CountryCode: "AFG"}).Find(&city)

where NOT 检索

db.Not("CountryCode =?", "USA").Find(&city)
db.Not(map[string]interface{}{"CountryCode": []string{"NLD", "IND", "CHN", "USA"}}).Find(&city)
db.Not(City{CountryCode: "USA", District: "Guangdong"}).Find(&city)

Or条件:

db.Where("CountryCode =?", "USA").Or(City{District: "Guangdong"}).Find(&city)

选择特定的column:

db.Select("ID", "Population").Find(&city)

排序order

db.Order("Population").Where(City{District: "Guangdong"}).Find(&city)
db.Order("CountryCode, Population desc").Where("Population > ?", "5000000").Find(&city)
db.Order("CountryCode").Order("Population desc").Where("Population > ?", "5000000").Find(&city)

不规则排序

db.Clauses(clause.OrderBy{
  Expression: clause.Expr{SQL: "FIELD(列名,?)", Vars: []interface{}{[]int{值1, 值2, ...}}, WithoutParentheses: true},
}).Find(&表struct)
// SELECT * FROM 表 ORDER BY FIELD(列名,值1, 值2, ...)

增添

使用db.Create()实现记录的创建。注意外键的关联和主键的唯一,否则会报错。

incity := City{ID: 5000, Name: "swwhome", CountryCode: "CHN", District: "swwdis", Population: 3}
db.Create(&incity) //{5000 swwhome CHN swwdis 3}

选择字段添加 Select()

// INSERT INTO `city` (`ID`,`Name`,`CountryCode`) VALUES (5005, ""swwhome, "CHN")
incity := City{ID: 5005, Name: "swwhome", CountryCode: "CHN", District: "swwdis", Population: 3}
db.Select("ID", "Name", "CountryCode").Create(&incity) //{5005 swwhome CHN '' 0}

忽略被选择字段,创建其他字段 Omit()

go
复制代码
incity := City{ID: 5006, Name: "swwhome", CountryCode: "CHN", District: "swwdis", Population: 3}
db.Omit("District").Create(&incity) //{5006 swwhome CHN '' 3}

批量创建。db.CreateInBatches(interface, size)能够实现分批创建,注意数据会全写进去,只是分批写进去。

incitys := []City{{ID: 4088, Name: "swwhome", CountryCode: "CHN", District: "swwdis", Population: 3},
		{ID: 4089, Name: "swwhome", CountryCode: "CHN", District: "swwdis", Population: 3},
		{ID: 4090, Name: "swwhome", CountryCode: "CHN", District: "swwdis", Population: 3},
		{ID: 4091, Name: "swwhome", CountryCode: "CHN", District: "swwdis", Population: 3}}
db.Create(&incitys)
db.CreateInBatches(&incitys, 2) //两个两个创建

更新

把id为4086的数据的Population属性从3改为4

Update()

db.Find(&city, 4086)
fmt.Println(city)
db.Model(&city).Update("Population", 4)
db.Find(&city, 4086)
fmt.Println(city)

批量条件更新,把所有Population属性为3的改为4

db.Table("city").Where("Population=?", 3).Updates(map[string]interface{}{"Population": 4})

删除

通常使用Delete()进行删除操作,这是一种软删除。拥有软删除能力的模型调用 Delete 时,记录不会更新进数据库。但GORM会将 DeletedAt 置为当前时间, 并且不能再通过普通的查询方法找到该记录。

db.Find(&city, 4090)
db.Delete(&city)

通过主键删除

db.Delete(&City{}, []int{4090, 4091})
db.Delete(&City{}, 4090)

条件删除

db.Where("Population=?", 4).Delete(&City{})

上面的步骤已经使用GORM在Go中连接MySQL数据库并实现了基本的增删改查操作。