go语言与数据库(GORM入门)

连接数据库(MySQL)

安装依赖

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() {
 // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
 db, _ := gorm.Open(mysql.New(mysql.Config{
  DSN: "root:Ljr19981204@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local",    // 账号密码地址端口
 }), &gorm.Config{

 })
 fmt.Println(db)
}

MySQL驱动高级配置

package main

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

func main() {
 // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
 db, _ := gorm.Open(mysql.New(mysql.Config{
  DSN: "root:Ljr19981204@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local",    // 账号密码地址端口
  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{
  // ...gorm配置
 })
 fmt.Println(db)
}

GORM配置

db, _ := gorm.Open(mysql.New(mysql.Config{
    // ...MySQL配置
}), &gorm.Config{
    SkipDefaultTransaction: true,      // 跳过默认事物
    // GORM 允许用户通过覆盖默认的NamingStrategy来更改命名约定
    NamingStrategy: schema.NamingStrategy{
        TablePrefix: "t_",          // 表名前缀,`User`表为`t_users`
        SingularTable: true,        // 使用单数表名,启用该选项后,`User` 表将是`user`
    },
    // 在 AutoMigrate 或 CreateTable 时,GORM 会自动创建外键约束,若要禁用该特性,可将其设置为 true
    DisableForeignKeyConstraintWhenMigrating: true,
    // 更改创建时间使用的函数
    NowFunc: func() time.Time {
        return time.Now().Local()
    },
})

连接池配置

// 直接通过上面连接得到的db,调用DB()函数返回即可设置
sqlDB, _ := db.DB()

// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)

// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)

// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)

模型

模型就是GO语言中的Struct结构体+标签

约定

GORM 倾向于约定,而不是配置。默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAtUpdatedAt 字段追踪创建、更新时间

gorm.Model

GORM 定义一个 gorm.Model 结构体,其包括字段 IDCreatedAtUpdatedAtDeletedAt

// gorm.Model 的定义
type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

可以将它嵌入到自定义的结构体中,以包含这几个字段

嵌入结构体

有如下自定义结构体User

type User struct {
 Name string
}

对于匿名字段,GORM 会将其字段包含在父结构体中,例如:

type User struct {
    gorm.Model   // 将GORM定义的gorm.Model结构体嵌入到User结构体中
    Name string
}
// 等效于
type User struct {
    ID        uint           `gorm:"primaryKey"`
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt gorm.DeletedAt `gorm:"index"`
    Name string
}

对于正常的结构体字段,也可以通过标签 embedded 将其嵌入,例如:

type Author struct {
    Name  string
    Email string
}

type Blog struct {
    ID      int
    Upvotes int32
    Author  Author `gorm:"embedded"`
}
// 等效于
type Blog struct {
    ID    int64
    Name  string
    Email string
    Upvotes  int32
}

字段标签

声明 model 时,tag 是可选的,GORM 支持以下 tag:tag 名大小写不敏感,但建议使用 camelCase 风格。

标签列表:

标签名 说明
column 指定 db 列名
type 列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not nullsize, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT
size 指定列大小,例如:size:256
primaryKey 指定列为主键
unique 指定列为唯一
default 指定列的默认值
precision 指定列的精度
scale 指定列大小
not null 指定列为 NOT NULL
autoIncrement 指定列为自动增长
autoIncrementIncrement 自动步长,控制连续记录之间的间隔
embedded 嵌套字段
embeddedPrefix 嵌入字段的列名前缀
autoCreateTime 创建时追踪当前时间,对于 int 字段,它会追踪秒级时间戳,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:nano
autoUpdateTime 创建/更新时追踪当前时间,对于 int 字段,它会追踪秒级时间戳,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli
index 根据参数创建索引,多个字段使用相同的名称则创建复合索引,查看 索引 获取详情
uniqueIndex index 相同,但创建的是唯一索引
check 创建检查约束,例如 check:age > 13,查看 约束 获取详情
<- 设置字段写入的权限, <-:create 只创建、<-:update 只更新、<-:false 无写入权限、<- 创建和更新权限
-> 设置字段读的权限,->:false 无读权限
忽略该字段,- 无读写权限
comment 迁移时为字段添加注释

示例:

type User struct {
 Model        gorm.Model `gorm:"embedded;embeddedPrefix:gorm_"`     // 嵌套字段,且嵌套字段前缀为gorm_
 Name         string `gorm:"column:username;comment:用户名"`      // 指定数据库列名为username,注释为用户名
 Email        *string `gorm:"unique;not null;comment:邮箱"`          // 指定列唯一,且为not null
 Age          uint8 `gorm:"default:18;comment:年龄"`           // 指定默认值为18
}

表迁移(自动生成数据表)

AutoMigrate

db.AutoMigrate(&User{})

直接通过db.AutoMigrate即可根据模型生成数据表,使用上述配置的MySQL和GORM以及User模型生成的数据表如下所示,结构体的每个属性都对应到数据表中的字段,且设置的字段标签也对应生效。

go语言与数据库(GORM入门)
image-20211214102139774

Migrator 接口

AutoMigrate方法只能简单的生成数据表,Migrator 接口为每个数据库提供了统一的 API 接口,可用来为您的数据库构建独立迁移。

// 获取当前数据库名
db.Migrator().CurrentDatabase()

表操作

// 为 `User` 创建表
db.Migrator().CreateTable(&User{})

// 将 "ENGINE=InnoDB" 添加到创建 `User` 的 SQL 里去
db.Set("gorm:table_options""ENGINE=InnoDB").Migrator().CreateTable(&User{})

// 检查 `User` 对应的表是否存在
db.Migrator().HasTable(&User{})
db.Migrator().HasTable("users")

// 如果存在表则删除(删除时会忽略、删除外键约束)
db.Migrator().DropTable(&User{})
db.Migrator().DropTable("users")

// 重命名表
db.Migrator().RenameTable(&User{}, &UserInfo{})
db.Migrator().RenameTable("users""user_infos")

列操作

type User struct {
  Name string
}

// 添加 name 字段
db.Migrator().AddColumn(&User{}, "Name")
// 删除 name 字段
db.Migrator().DropColumn(&User{}, "Name")
// 修改 name 字段
db.Migrator().AlterColumn(&User{}, "Name")
// 检查字段是否存在
db.Migrator().HasColumn(&User{}, "Name")

type User struct {
  Name    string
  NewName string
}

// 重命名字段
db.Migrator().RenameColumn(&User{}, "Name""NewName")
db.Migrator().RenameColumn(&User{}, "name""new_name")

// 获取字段类型
db.Migrator().ColumnTypes(&User{}) ([]*sql.ColumnType, error)

索引操作

type User struct {
  gorm.Model
  Name string `gorm:"size:255;index:idx_name,unique"`
}

// 为 Name 字段创建索引
db.Migrator().CreateIndex(&User{}, "Name")
db.Migrator().CreateIndex(&User{}, "idx_name")

// 为 Name 字段删除索引
db.Migrator().DropIndex(&User{}, "Name")
db.Migrator().DropIndex(&User{}, "idx_name")

// 检查索引是否存在
db.Migrator().HasIndex(&User{}, "Name")
db.Migrator().HasIndex(&User{}, "idx_name")

type User struct {
  gorm.Model
  Name  string `gorm:"size:255;index:idx_name,unique"`
  Name2 string `gorm:"size:255;index:idx_name_2,unique"`
}
// 修改索引名
db.Migrator().RenameIndex(&User{}, "Name""Name2")
db.Migrator().RenameIndex(&User{}, "idx_name""idx_name_2")


go语言与数据库(GORM入门)


原文始发于微信公众号(良猿):go语言与数据库(GORM入门)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/215926.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!