摒弃世俗浮躁
追求技术精湛

Golang笔记(六):数据库操作(GORM)

GORM

GORM 取名自 Go ORM,GORM 是优秀的Golang ORM 类库。
项目地址:https://github.com/go-gorm/gorm
文档地址:https://learnku.com/docs/gorm/v2

什么是ORM?

ORM 全称是:Object Relational Mapping(对象关系映射),其主要作用是在编程中,把面向对象的概念跟数据库中表的概念对应起来。举例来说就是,我定义一个对象(结构体),那就对应着一张表,这个对象的实例,就对应着表中的一条记录。

安装 GORM

首先执行下述命令安装GORM

$ go get -u gorm.io/gorm

在安装 GORM 的同时,我们还需要安装 GORM 的 MySQL 的数据库驱动

$ go get -u gorm.io/driver/mysql

初始化连接

./pkg/model/model.go:

// DB gorm.DB 对象
var DB *gorm.DB

// ConnectDB 初始化模型
func ConnectDB() *gorm.DB {
	var err error
	config := mysql.New(mysql.Config{
		DSN: "root:FLHY1VJ0WEOBIG3N@tcp(127.0.0.1:3306)/goblog?charset=utf8&parseTime=True&loc=Local",
	})

	DB, err = gorm.Open(config, &gorm.Config{
		// GORM Logger日志级别:
		// Silent 静默模式,不打印任何信息
		// Error 发生错误了才打印
		// Warn 发生警告级别以上的错误才打印(默认)
		// Info 打印所有信息,包括 SQL 语句
		Logger: gormlogger.Default.LogMode(gormlogger.Warn),
	})

	logger.LogError(err)
	return DB
}

./bootstrap/db.go:

func SetupDB() {
	db := model.ConnectDB()
	sqlDB, _ := db.DB()

	// 设置最大连接数
	sqlDB.SetMaxOpenConns(100)
	// 设置最大空闲连接
	sqlDB.SetMaxIdleConns(25)
	// 设置每个连接的过期时间
	sqlDB.SetConnMaxLifetime(5 * time.Minute)
}

./main.go:

func main() {
        // 初始化数据库
	bootstrap.SetupDB()
}

自动迁移

可以根据设置的模型 Struct 来自动创建数据表结构,免去了手动维护 SQL 的烦恼。
使用自动迁移很简单,只需要调用 AutoMigrate() 方法并将数据模型 Struct 传参进去即可。
因为这是一个全局动作,所以这个操作通常是放置于数据库初始化的地方:

// SetupDB 初始化数据库和 ORM
func SetupDB() {
    ... 省略代码 ...
    // 创建和维护数据表结构
    migration(db)
}

func migration(db *gorm.DB) {
    // 自动迁移
    db.AutoMigrate(
        &user.User{},
        &article.Article{},
    )
}

GORM 的自动迁移工具不支持版本,只能保持字段与传参的 Struct 一致,无法删除字段。所以我们将自动迁移的代码封装到 migration() 方法里,以后遇到需要删除字段的情况,将这些代码写到此方法即可。

字段标签

按照上面自动迁移的方式创建的字段基本都不符合我们的需求,我们可以通过设置 GORM 模型的 Struct Tag 来解决:

// User 用户模型
type User struct {
	models.BaseModel

	Name     string `gorm:"type:varchar(255);not null;unique"`
	Email    string `gorm:"type:varchar(255);unique"`
	Password string `gorm:"type:varchar(255)"`

	// gorm:"-" 设置 GORM 在读写时略过此字段
	PasswordConfirm string `gorm:"-"`
}
声明 GORM 数据模型时,字段标签是可选的,GORM 支持以下:(注:名大小写不敏感,但建议使用 camelCase 风格)
标签名说明
column指定 db 列名
type列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null、size, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSINED not NULL AUTO_INSTREMENT
size指定列大小,例如:size:256
primaryKey指定列为主键
unique指定列为唯一
default指定列的默认值
precision指定列的精度
scale指定列大小
not null指定列为 NOT NULL
autoIncrement指定列为自动增长
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 无读权限
忽略该字段,- 无读写权限

Hooks

钩子函数是在创建、查询、更新、删除之前 或之后 调用的函数。
如果为模型定义了指定的方法,则在创建、更新、查询和删除时将自动调用该模型,并且如果有任何回调返回错误,GORM 将停止接下来的操作并回滚事务。

这里拿 Create 相关的 Hook 举个例子

可用于创建的钩子函数:

//开始事务
BeforeSave 
BeforeCreate 
//在关联之前保存
//插入数据库
//在关联之后保存
AfterCreate 
AfterSave 
//提交或回滚事务

代码示例:

// BeforeCreate GORM 的模型钩子,创建模型前调用
func (user *User) BeforeCreate(tx *gorm.DB) (err error) {
	user.Password = password.Hash(user.Password)
	return
}

// BeforeUpdate GORM 的模型钩子,更新模型前调用
func (user *User) BeforeUpdate(tx *gorm.DB) (err error) {
	if !password.IsHashed(user.Password) {
		user.Password = password.Hash(user.Password)
	}
	return
}

注意:GORM 中的保存和删除操作默认是运行在事务当中,所以在事务当中所作的更改在它被提交之前是不可见的,如果在钩子中返回任何的错误,更改将被回滚。

另:GORM CURD 的用法太多了,具体的还是等使用的时去参考文档吧 :)
赞(0) 打赏
未经允许不得转载:时光日记 » Golang笔记(六):数据库操作(GORM)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册