GORM 使用一个名为ID每个模型的默认主键的字段。
- type User struct {
- ID string // 默认情况下,名为 `ID` 的字段会作为表的主键
- Name string
- }
可以通过标签 primaryKey 将其它字段设为主键
- // 将 `UUID` 设为主键
- type Animal struct {
- ID int64
- UUID string `gorm:"primaryKey"`
- Name string
- Age int64
- }
默认情况下,GORM 将结构名称转换为snake_case表名称并将其复数化。例如,一个User结构体出现users在数据库中。
您可以实现 Tabler 接口来更改默认表名,例如:
- type Tabler interface {
- TableName() string
- }
-
- // TableName 会将 User 的表名重写为 `profiles`
- func (User) TableName() string {
- return "profiles"
- }
注意: TableName 不支持动态变化,它会被缓存下来以便后续使用。想要使用动态表名,你可以使用 Scopes,例如:
- func UserTable(user User) func (tx *gorm.DB) *gorm.DB {
- return func (tx *gorm.DB) *gorm.DB {
- if user.Admin {
- return tx.Table("admin_users")
- }
-
- return tx.Table("users")
- }
- }
-
- db.Scopes(UserTable(user)).Create(&user)
临时指定表名
您可以使用 Table 方法临时指定表名,例如:
- // 根据 User 的字段创建 `deleted_users` 表
- db.Table("deleted_users").AutoMigrate(&User{})
-
- // 从另一张表查询数据
- var deletedUsers []User
- db.Table("deleted_users").Find(&deletedUsers)
- // SELECT * FROM deleted_users;
-
- db.Table("deleted_users").Where("name = ?", "jinzhu").Delete(&User{})
- // DELETE FROM deleted_users WHERE name = 'jinzhu';
GORM 自动将结构体字段名转换为snake_case数据库中的列名。
- type User struct {
- ID uint // 列名是 `id`
- Name string // 列名是 `name`
- Birthday time.Time // 列名是 `birthday`
- CreatedAt time.Time // 列名是 `created_at`
- }
您可以使用 column 标签或 命名策略 来覆盖列名
- type Animal struct {
- AnimalID int64 `gorm:"column:beast_id"` // 将列名设为 `beast_id`
- Birthday time.Time `gorm:"column:day_of_the_beast"` // 将列名设为 `day_of_the_beast`
- Age int64 `gorm:"column:age_of_the_beast"` // 将列名设为 `age_of_the_beast`
- }
你可以通过将 autoCreateTime 标签置为 false 来禁用时间戳追踪,例如:
- type User struct {
- CreatedAt time.Time `gorm:"autoCreateTime:false"`
- }
GORM 使用名为CreatedAt和的字段UpdatedAt来自动跟踪记录的创建和更新时间。
对于有 CreatedAt 字段的模型,创建记录时,如果该字段值为零值,则将该字段的值设为当前时间
- db.Create(&user) // 将 `CreatedAt` 设为当前时间
-
- user2 := User{Name: "jinzhu", CreatedAt: time.Now()}
- db.Create(&user2) // user2 的 `CreatedAt` 不会被修改
-
- // 想要修改该值,您可以使用 `Update`
- db.Model(&user).Update("CreatedAt", time.Now())
对于有 UpdatedAt 字段的模型,更新记录时,将该字段的值设为当前时间。创建记录时,如果该字段值为零值,则将该字段的值设为当前时间
- db.Save(&user) // 将 `UpdatedAt` 设为当前时间
-
- db.Model(&user).Update("name", "jinzhu") // 会将 `UpdatedAt` 设为当前时间
-
- db.Model(&user).UpdateColumn("name", "jinzhu") // `UpdatedAt` 不会被修改
-
- user2 := User{Name: "jinzhu", UpdatedAt: time.Now()}
- db.Create(&user2) // 创建记录时,user2 的 `UpdatedAt` 不会被修改
-
- user3 := User{Name: "jinzhu", UpdatedAt: time.Now()}
- db.Save(&user3) // 更新时,user3 的 `UpdatedAt` 会修改为当前时间
你可以通过将 autoUpdateTime 标签置为 false 来禁用时间戳追踪,例如:
- type User struct {
- UpdatedAt time.Time `gorm:"autoUpdateTime:false"`
- }
要在有mod文件的文件夹下面执行下面的命令
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

- package main
- import (
- "fmt"
- "gorm.io/driver/mysql"
- "gorm.io/gorm"
- )
- func main() {
- // 参考 root:123456@tcp(192.168.31.131:3306)/gotest
- dsn := "root:123456@tcp(192.168.31.131:3306)/gotest?charset=utf8mb4&parseTime=True&loc=Local"
- db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
- if err != nil {
- fmt.Println("连接失败")
- return
- }
- fmt.Println("连接成功", db)
- }

- package main
- import (
- "fmt"
- "gorm.io/driver/mysql"
- "gorm.io/gorm"
- )
- func main() {
- // 参考 root:123456@tcp(192.168.31.131:3306)/gotest
- dsn := "root:123456@tcp(192.168.31.131:3306)/gotest?charset=utf8mb4&parseTime=True&loc=Local"
- db, err := gorm.Open(mysql.New(mysql.Config{
- DSN: dsn, // DSN data source name
- DefaultStringSize: 256, // string 类型字段的默认长度
- DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
- DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
- DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
- SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
- }), &gorm.Config{})
- if err != nil {
- fmt.Println("连接失败")
- return
- }
- fmt.Println("连接成功", db)
- }
crud

- package main
- import (
- "errors"
- "fmt"
- "gorm.io/driver/mysql"
- "gorm.io/gorm"
- )
- type Stu struct {
- Id int `gorm:"primaryKey"`
- Name string
- Age int
- Address string
- }
-
- func getDb() *gorm.DB {
- dsn := "root:123456@tcp(192.168.31.131:3306)/gotest?charset=utf8mb4&parseTime=True&loc=Local"
- db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
- if err != nil {
- fmt.Println("连接失败")
- panic(errors.New("连接失败"))
- }
- fmt.Println("连接成功", db)
- return db
- }
注意结构体中的属性首字母要大写,否则就不可见,还要指定主键
需要带条件的可以自己查看api

获取第一条记录(主键升序)
- func main() {
- db := getDb()
- testFirst(db)
- }
- func testFirst(db *gorm.DB) {
- var stu Stu
- res := db.Table("stu").First(&stu)
- if res.Error != nil {
- fmt.Println("查询数据失败")
- return
- }
- fmt.Println(stu)
- }

获取一条记录,没有指定排序字段
- func testTake(db *gorm.DB) {
- var stu Stu
- res := db.Table("stu").Take(&stu)
- if res.Error != nil {
- fmt.Println("查询数据失败")
- return
- }
- fmt.Println(stu)
- }
获取最后一条记录(主键降序)
- func testLast(db *gorm.DB) {
- var stu Stu
- res := db.Table("stu").Last(&stu)
- if res.Error != nil {
- fmt.Println("查询数据失败")
- return
- }
- fmt.Println(stu)
- }
- func testMany(db *gorm.DB) {
- var stus = make([]Stu, 0)
- //相当于条件是id为10
- _ = db.Table("stu").Find(&stus)
- fmt.Println(stus)
- }
如果表不存在,会创建表
- func testAddOne(db *gorm.DB) {
- stu := Stu{Name: "新增名称", Age: 11, Address: "新增地址"}
- tx := db.Table("stu").Create(&stu)
- if tx.Error != nil {
- fmt.Println("新增失败")
- return
- }
- fmt.Println(stu.Id)
- }
- func testAddMany(db *gorm.DB) {
- stus := []Stu{{Name: "批量新增名称1", Age: 11, Address: "批量新增地址1"}, {Name: "批量新增名称2", Age: 11, Address: "批量新增地址2"}}
- tx := db.Table("stu").Create(&stus)
- if tx.Error != nil {
- fmt.Println("新增失败")
- return
- }
- fmt.Println(stus)
- }
- func testUpdateOne(db *gorm.DB) {
- var stu Stu
- _ = db.Table("stu").First(&stu)
- stu.Name = "更新后名字"
- db.Table("stu").Save(&stu)
- }
- func testUpdateOne1(db *gorm.DB) {
- db.Table("stu").Where("id=?", 72).Update("name", "更新").Update("address", "跟新地址")
- }
- func testUpdateMany(db *gorm.DB) {
- db.Table("stu").Where("id in (?)", []int{1,2,3,43}).Update("name", "更新").Update("address", "跟新地址")
- }
- func testDeleteMany(db *gorm.DB) {
- db.Table("stu").Where("id in (?)", []int{1, 2, 3, 43}).Delete(&Stu{})
- }