前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

Gorm

作者头像
TomatoCool
发布2023-10-16 08:16:00
2450
发布2023-10-16 08:16:00
举报
文章被收录于专栏:TomatoCoolTomatoCool

连接数据库

Mysql

代码语言:javascript
复制
dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

表操作

自动迁移

自动迁移仅仅会创建表,缺少列和索引,并且不会改变现有列的类型或删除未使用的列以保护数据。

代码语言:javascript
复制
db.AutoMigrate(&User{})
db.AutoMigrate(&User{}, &Product{}, &Order{})

判断表是否存在

代码语言:javascript
复制
//  检查模型`User`表是否存在
db.HasTable(&User{})
//  检查表`users`是否存在
db.HasTable("users")

创建表

代码语言:javascript
复制
db.CreateTable(&User{})

删除表

代码语言:javascript
复制
//  删除模型`User`的表
db.DropTable(&User{})
//  删除表`users`
db.DropTable("users")
//  删除模型`User`的表和表`products`
db.DropTableIfExists(&User{}, "products")

列操作

修改列

代码语言:javascript
复制
//  修改模型`User`的description列的数据类型为`text`
db.Model(&User{}).DropColumn("description")

删除列

代码语言:javascript
复制
db.Model(&User{}).DropColumn("description")

模型

定义模型

模型就是go语言中的结构体。

代码语言:javascript
复制
type User struct {
gorm.Model
Age          int
Name         string
}

表名

通过模型创建的表名为该模型名称的复数形式。可以通过重写TableName方法来修改。

代码语言:javascript
复制
//  设置User的表名为`profiles`
func (User) TableName() string {
    return "profiles"
}

可以禁用全局复数模式,这样表名会与结构体名相同。

代码语言:javascript
复制
db.SingularTable(true)

可以通过重写DefaultTableNameHandler函数更改表名的生成方式。

代码语言:javascript
复制
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string  {
    return "prefix_" + defaultTableName;
}

列名

列名是字段名的蛇形小写。可以通过标签自定义字段对应的列名。

代码语言:javascript
复制
// 重设列名
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`
}

外键

属于关系

默认使用关联属性类型的主键作为关联外键,关联属性类型 + 主键组成外键名。使用AssociationForeignKey标签自定义关联外键,foreignkey标签自定义外键。 User属于ProfileProfileID为外键。

代码语言:javascript
复制
type User struct {
    gorm.Model
    //  指定ProfileID为外键(默认)
    //  指定ID为关联外键(默认)
    Profile   Profile  `gorm:"ForeignKey:ProfileID;AssociationForeignKey:ID"`
    //  外键
    ProfileID int
}
//  它的ID是关联外键
type Profile struct {
    gorm.Model
    Name      string
}

查询示例

代码语言:javascript
复制
//  已知user,把它的Profile赋值给profile
db.Model(&user).Related(&profile)
一对一

User包含一个CreditCardUserID为外键。

代码语言:javascript
复制
type User struct {
    gorm.Model
    //  指定UserID为外键(默认)
    //  指定ID为关联外键(默认)
    CreditCard   CreditCard  `gorm:"ForeignKey:UserID;AssociationForeignKey:ID"`
}
type CreditCard struct {
    gorm.Model
    //  外键
    UserID   uint
    Number   string
}

查询示例

代码语言:javascript
复制
//  已知user,把它的CreditCard 赋值给card
db.Model(&user).Related(&card, "CreditCard")
一对多

User包含多个emailsUserID为外键

代码语言:javascript
复制
type User struct {
    gorm.Model
    //  指定UserID为外键(默认)
    //  指定ID为关联外键(默认)
    Emails   []Email  `gorm:"ForeignKey:UserID;AssociationForeignKey:ID"`
}
type Email struct {
    gorm.Model
    Email   string
    //  外键
    UserID  uint
}

查询示例

代码语言:javascript
复制
//  已知user,把它的Email赋值给emails
db.Model(&user).Related(&emails)
多对多

User包含并属于多个languages,使用user_languages表连接,默认使用两个表的ID作为外键。

代码语言:javascript
复制
type User struct {
    gorm.Model
    Languages         []Language `gorm:"many2many:user_languages;"`
}
type Language struct {
    gorm.Model
    Name string
}

查询示例

代码语言:javascript
复制
//  已知user,把它的Language赋值给language
db.Model(&user).Related(&languages, "Languages")
关联模式

从关联字段中查询

代码语言:javascript
复制
//  将user关联的Languages赋值给languages
db.Model(&user).Association("Languages").Find(&languages)

添加新的many2many, has_many关联

代码语言:javascript
复制
//  向user关联的Languages添加Language实例
db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN})
db.Model(&user).Association("Languages").Append(Language{Name: "DE"})

删除源和传递的参数之间的关系,不会删除这些参数

代码语言:javascript
复制
db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN})
db.Model(&user).Association("Languages").Delete(languageZH, languageEN)

使用新的关联替换当前关联

代码语言:javascript
复制
db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN})
db.Model(&user).Association("Languages").Replace(Language{Name: "DE"}, languageEN)

返回当前关联的计数

代码语言:javascript
复制
db.Model(&user).Association("Languages").Count()

删除源和当前关联之间的关系,不会删除这些关联

代码语言:javascript
复制
db.Model(&user).Association("Languages").Clear()

数据读写

创建

代码语言:javascript
复制
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
db.Create(&user)

查询

代码语言:javascript
复制
var user User
var users []User

// 获取第一条记录,按主键排序
db.First(&user)

// 获取最后一条记录,按主键排序
db.Last(&user)

// 获取所有记录
db.Find(&users)

// 使用主键获取记录
db.First(&user, 10)

Where查询(SQL)

代码语言:javascript
复制
//  简单查询
db.Where("name = ?", "lihua").First(&user)
//  IN查询
db.Where("name in (?)", []string{"lihua", "lihuahua"}).Find(&users)
//  LIKE查询
db.Where("name LIKE ?", "%li%").Find(&users)
//  AND查询
db.Where("name = ? AND age >= ?", "lihua", "20").Find(&users)
//  按日期查询
db.Where("updated_at > ?", lastWeek).Find(&users)
db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)

Where查询(Struct)

代码语言:javascript
复制
db.Where(&User{Name: "lihua", Age: 20}).First(&user)

Where查询(Map)

代码语言:javascript
复制
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)

Where查询(Slice)

代码语言:javascript
复制
//  按主键查询
db.Where([]int64{20, 21, 22}).Find(&users)

Not查询

代码语言:javascript
复制
db.Not("name", "lihua").First(&user)

Or查询

代码语言:javascript
复制
db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)

查询链

代码语言:javascript
复制
db.Where("name <> ?","lihua").Where("age >= ? and role <> ?",20,"admin").Find(&users)

查询或初始化

代码语言:javascript
复制
//  存在则赋值给user,否则初始化后再赋值给user
db.FirstOrInit(&user, User{Name: "lihua"})
//  不存在时初始化,并指定参数
db.Attrs(User{Age: 20}).FirstOrInit(&user, User{Name: "lihua"})
//  无论是否存在,都将参数分配到结果
db.Assign(User{Age: 20}).FirstOrInit(&user, User{Name: "lihua"})

查询或创建

代码语言:javascript
复制
//  存在则赋值给user,否则创建后再赋值给user
db.FirstOrCreate(&user, User{Name: "lihua"})
//  不存在时创建,并指定参数
db.Attrs(User{Age: 20}).FirstOrCreate(&user, User{Name: "lihua"})
//  无论是否存在,都将参数分配到结果并保存到数据库
db.Assign(User{Age: 20}).FirstOrCreate(&user, User{Name: "lihua"})

Select查询

代码语言:javascript
复制
db.Select("name, age").Find(&users)
db.Select([]string{"name", "age"}).Find(&users)
db.Table("users").Select("COALESCE(age,?)", 42).Rows()

Order排序

代码语言:javascript
复制
db.Order("age desc, name").Find(&users)
db.Order("age desc").Order("name").Find(&users)
//  重新排序
db.Order("age desc").Find(&users1).Order("age", true).Find(&users2)

Limit指定数量

代码语言:javascript
复制
db.Limit(3).Find(&users)
//  取消Limit
db.Limit(10).Find(&users1).Limit(-1).Find(&users2)

Offset跳过记录

代码语言:javascript
复制
//  跳过前三个
db.Offset(3).Find(&users)
//  取消跳过
db.Offset(10).Find(&users1).Offset(-1).Find(&users2)

获取记录数

代码语言:javascript
复制
db.Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Find(&users).Count(&count)

更新

更新全部字段

代码语言:javascript
复制
db.First(&user)
user.Name = "lihuahua"
user.Age = 100
db.Save(&user)

更新指定字段

代码语言:javascript
复制
db.Model(&user).Update("name", "hello")
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
//  不会更新值为"",0,false的字段
db.Model(&user).Updates(User{Name: "hello", Age: 18})

指定字段更新,其它忽略

代码语言:javascript
复制
db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})

指定字段忽略,其它更新

代码语言:javascript
复制
db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})

删除

代码语言:javascript
复制
// 删除存在的记录
db.Delete(&email)
//  添加额外SQL选项
db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email)

批量删除

代码语言:javascript
复制
db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
db.Delete(Email{}, "email LIKE ?", "%jinzhu%")

软删除 如果模型有DeletedAt字段,它将自动获得软删除功能! 那么在调用Delete时不会从数据库中永久删除,而是只将字段DeletedAt的值设置为当前时间。

代码语言:javascript
复制
//  查找软删除的记录
db.Unscoped().Where("age = 20").Find(&users)
//  永久删除
db.Unscoped().Delete(&user)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 连接数据库
    • Mysql
    • 表操作
      • 自动迁移
        • 判断表是否存在
          • 创建表
            • 删除表
            • 列操作
              • 修改列
                • 删除列
                • 模型
                  • 定义模型
                    • 表名
                      • 列名
                        • 外键
                          • 属于关系
                          • 一对一
                          • 一对多
                          • 多对多
                          • 关联模式
                      • 数据读写
                        • 创建
                          • 查询
                            • 更新
                              • 删除
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档