gorm连接mysql数据库以及建表和自动迁移

  • 前言
  • 连接
  • 连接数据库
  • 配置mysql
  • 配置gorm
  • 常规数据库接口-连接池
  • 迁移
  • 自动迁移建表
  • 手动迁移建表
  • Migrator接口
  • 常用的Migrator方法
  • 创建表
  • 是否存在表
  • 删除表
  • 重命名表
  • 更多的api


前言

本书皆是对官方文档常用的内容进行描述

包括:连接数据库,建表,自动迁移,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)
	}
}

gorm 打开mysql数据库连接但是没关闭会怎么样 gorm数据库连接池_mariadb

手动迁移建表

我们查看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")

gorm 打开mysql数据库连接但是没关闭会怎么样 gorm数据库连接池_表名_02


这个时候再通过原来的结构体查询就查不到了

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使用直接翻阅官方文档迁移即可