本文重点:
db.AutoMigrate()这个函数的理解:
AutoMigrate是GORM提供的一个方法,用于自动迁移你的模型(即数据库表结构)到数据库中,确保数据库表与你的Go结构体(模型)保持一致。
首先,你需要定义你的模型(结构体),这些结构体将映射到数据库中的表。然后,你可以使用GORM的AutoMigrate方法来自动创建或更新这些表。
AutoMigrate做了什么?
创建表:如果数据库中不存在与模型对应的表,AutoMigrate会创建这个表。
添加缺失的字段:如果表中缺少模型中的某些字段,AutoMigrate会添加这些字段。
修改字段类型(在某些情况下):如果字段类型与模型中的类型不匹配,AutoMigrate会尝试修改字段类型(但请注意,这取决于数据库和GORM版本,某些情况下可能不支持自动修改字段类型)。
不会删除字段:如果模型中的某些字段在表中不存在,AutoMigrate不会从表中删除任何字段。
如果哪个表已存在呢?
当products表已经存在于数据库中时,GORM的AutoMigrate方法会采取不同的行为,具体取决于表的当前状态与你的模型(Go结构体)之间的差异。以下是几种可能的情况:
- 无差异:如果products表的结构与你的Product模型完全匹配(包括字段名、字段类型、索引等),AutoMigrate可能不会执行任何操作,因为没有必要进行迁移。
- 缺少字段:如果products表中缺少你的Product模型中定义的某些字段,AutoMigrate会尝试向表中添加这些缺失的字段。然而,并非所有数据库都支持在已存在的表中添加新字段,这取决于数据库的类型和版本。
- 字段类型不匹配:如果products表中已存在的字段类型与你的Product模型中定义的字段类型不匹配,AutoMigrate的行为将取决于具体的数据库和GORM版本。在某些情况下,它可能会尝试修改字段类型(但通常这并不可行,因为修改已存在的字段类型可能会导致数据丢失或损坏)。在其他情况下,它可能会忽略类型不匹配并继续执行其他迁移操作。
- 不会删除字段:无论你的Product模型中是否缺少products表中的某些字段,AutoMigrate都不会从表中删除任何字段。它只负责添加缺失的字段或修改不匹配的类型(在可能的情况下)。
- 索引和约束:AutoMigrate还会处理索引和约束。如果Product模型中定义了索引或约束,并且这些索引或约束在products表中不存在,AutoMigrate会尝试创建它们。但是,如果products表中已经存在这些索引或约束,AutoMigrate可能会跳过它们的创建,或者在某些情况下更新它们(尽管更新索引和约束的行为通常比添加新字段更复杂,且不是所有数据库都支持)。
- 数据迁移:重要的是要注意,AutoMigrate主要负责表结构的迁移,而不是数据的迁移。如果你需要迁移数据(例如,从旧模型迁移到新模型),你可能需要编写额外的代码来处理这种情况。
- 谨慎使用:由于AutoMigrate可能会修改数据库表结构,因此在生产环境中使用时需要特别小心。在将更改应用于生产数据库之前,最好在开发或测试环境中进行测试,以确保迁移操作不会破坏现有数据或导致意外的副作用。
总之,当products表已存在时,GORM的AutoMigrate方法会根据你的模型与表之间的差异来执行相应的迁移操作。但是,它不会删除任何字段或修改现有数据(除了在某些特定情况下可能尝试修改字段类型或索引/约束)。因此,在使用AutoMigrate时需要谨慎,并确保你的模型与数据库表结构保持一致。
go
package main
import (
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
//定义模型
type User struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"size:255"`
Age int `gorm:"type:int"`
Birthday time.Time `gorm:"type:date"`
}
func main() {
dsn := "root:828924@tcp(127.0.0.1:3306)/user?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
user := User{
Name: "jinzhu",
Age: 18,
Birthday: time.Now(),
}
db.AutoMigrate(&User{})
//插入一条数据
db.Create(&user)
//插入多条数据
users := []User{
{Name: "jinzhu1", Age: 18, Birthday: time.Now()},
{Name: "jinzhu2", Age: 18, Birthday: time.Now()},
}
db.Create(users)
}