前言
本书皆是对官方文档常用的内容进行描述
包括:连接数据库,建表,自动迁移,Migrator接口
连接
连接数据库
连接到数据库
最简单的连接方式
import ( "fmt" "gorm.io/driver/mysql" "gorm.io/gorm" ) func main() { //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{}) //想要正确的处理 time.Time ,您需要带上 parseTime 参数, (更多参数) 要支持完整的 UTF-8 编码,您需要将 charset=utf8 更改为 charset=utf8mb4 查看 此文章 获取详情 dsn := "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) fmt.Println(db, err) }
配置mysql
但是我们在使用的过程中,还会对数据库连接进行一些设置,MySQl 驱动程序提供了 一些高级配置 可以在初始化过程中使用。更多配置见官方文档
func main() { dsn := "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.New(mysql.Config{ DSN: dsn, 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{}) fmt.Println(db, err) }
配置gorm
不仅仅是mysql连接可以配置,我们对gorm也可以进行配置。更多配置见官方文档
GORM 配置
func main() { dsn := "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.New(mysql.Config{ DSN: dsn, }), &gorm.Config{ SkipDefaultTransaction: false, //跳过默认事务 NamingStrategy: schema.NamingStrategy{ SingularTable: true, // 复数形式 User的表名应该是users TablePrefix: "t_", //表名前缀 User的表名应该是t_users }, DisableForeignKeyConstraintWhenMigrating: true, //设置成为逻辑外键(在物理数据库上没有外键,仅体现在代码上) }) fmt.Println(db, err) }
常规数据库接口-连接池
GORM 提供了 DB 方法,可用于从当前 *gorm.DB 返回一个通用的数据库接口 *sql.DB
func main() { dsn := "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.New(mysql.Config{ DSN: dsn, }), &gorm.Config{ SkipDefaultTransaction: false, //跳过默认事务 NamingStrategy: schema.NamingStrategy{ SingularTable: false, // 复数形式 User的表名应该是users TablePrefix: "gva_", //表名前缀 User的表名应该是t_users }, DisableForeignKeyConstraintWhenMigrating: true, //设置成为逻辑外键(在物理数据库上没有外键,仅体现在代码上) }) // 获取通用数据库对象 sql.DB ,然后使用其提供的功能 sqlDB, err := db.DB() // SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。 sqlDB.SetMaxIdleConns(10) // SetMaxOpenConns 设置打开数据库连接的最大数量。 sqlDB.SetMaxOpenConns(100) // SetConnMaxLifetime 设置了连接可复用的最大时间。 sqlDB.SetConnMaxLifetime(time.Hour) }
迁移
迁移
自动迁移建表
func main() { dsn := "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.New(mysql.Config{ DSN: dsn, }), &gorm.Config{ SkipDefaultTransaction: false, //跳过默认事务 NamingStrategy: schema.NamingStrategy{ SingularTable: true, // 复数形式 User的表名应该是users TablePrefix: "gva_", //表名前缀 User的表名应该是t_users }, DisableForeignKeyConstraintWhenMigrating: true, //设置成为逻辑外键(在物理数据库上没有外键,仅体现在代码上) }) fmt.Println(db, err) type User struct { Name string } err = db.AutoMigrate(&User{}) if err != nil { fmt.Println(err) } }
手动迁移建表
我们查看db.AutoMigrate,发现其内部是调用了一个接口type Migrator interface
,里面有很多方法,Migrator
接口是一个统一的ap接口
func (db *DB) AutoMigrate(dst ...interface{}) error { return db.Migrator().AutoMigrate(dst...) } // Migrator migrator interface type Migrator interface { //下一小节 }
所以我们可以自动去建表
m:=db.Migrator() m.CreateTable(&User{})
Migrator接口
我们发现该接口有很多方法
// Migrator migrator interface type Migrator interface { // AutoMigrate AutoMigrate(dst ...interface{}) error // Database CurrentDatabase() string FullDataTypeOf(*schema.Field) clause.Expr // Tables CreateTable(dst ...interface{}) error DropTable(dst ...interface{}) error HasTable(dst interface{}) bool RenameTable(oldName, newName interface{}) error GetTables() (tableList []string, err error) // Columns AddColumn(dst interface{}, field string) error DropColumn(dst interface{}, field string) error AlterColumn(dst interface{}, field string) error MigrateColumn(dst interface{}, field *schema.Field, columnType ColumnType) error HasColumn(dst interface{}, field string) bool RenameColumn(dst interface{}, oldName, field string) error ColumnTypes(dst interface{}) ([]ColumnType, error) // Views CreateView(name string, option ViewOption) error DropView(name string) error // Constraints CreateConstraint(dst interface{}, name string) error DropConstraint(dst interface{}, name string) error HasConstraint(dst interface{}, name string) bool // Indexes CreateIndex(dst interface{}, name string) error DropIndex(dst interface{}, name string) error HasIndex(dst interface{}, name string) bool RenameIndex(dst interface{}, oldName, newName string) error }
常用的Migrator方法
创建表
m:=db.Migrator() m.CreateTable(&User{})
是否存在表
//以结构体的方式查 m.HasTable(&User{}) //以表名的方式查 fmt.Println(m.HasTable("gva_users"))
删除表
err = m.DropTable(&User{}) if err != nil { fmt.Println(err) } err = m.DropTable("gva_users") if err != nil { fmt.Println(err) } if m.HasTable(&User{}) { m.DropTable(&User{}) } else { m.CreateTable(&User{}) }
重命名表
将gva_users表改为gva_users_two表
m := db.Migrator() m.RenameTable(&User{}, "gva_users_two")
这个时候再通过原来的结构体查询就查不到了
fmt.Println( m.HasTable(&User{}))//false
所以一般建议这样写
type User struct { Name string } m := db.Migrator() type UserTwo struct { Name string } m.RenameTable(&User{},&UserTwo{})
更多的api
可以看到,这些api都是在type Migrator interface
这个结构体中,所以直接看该接口有哪些方法即可,更多的api使用直接翻阅官方文档迁移即可