Go 框架三件套详解之Gorm(1) | 青训营笔记

89 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天

1、Gorm介绍

ORM框架

image.png

官方文档: GORM Guides | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

2、Gorm下载

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

3、快速开始

导入模块

package main

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

声明Gorm Model(定义表的字段)

可以这样声明(不常用)

type Product struct {
    ID        uint           `gorm:"primaryKey"`   
    CreatedAt time.Time   
    UpdatedAt time.Time   
    DeletedAt gorm.DeletedAt `gorm:"index"` 
    Code  string
    Price uint
}

GORM更喜欢约定而不是配置。默认情况下,使用GORM作为主键,将结构名复数化为表名和列名,并使用来跟踪创建/更新

gorm.Model GORM定义了一个结构体

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

可以将其嵌入到结构体中以包含这些字段

type Product struct {
  gorm.Model
  Code  string
  Price uint
}

连接数据库

func main() {
      db, err := gorm.Open(mysql.Open("root:123456@tcp(127.0.0.1:3306)/world?charset=utf8"), 
      &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }

mysql.Open打开数据库

root:123456@tcp(127.0.0.1:3306)/world?charset=utf8

连接名:密码@tcp(地址:端口号)/数据库名?配置信息

自动迁移 Auto Migration

自动迁移schema,以使schema保持最新。 注意:AutoMigrate将创建表、缺少外键、约束、列和索引。如果现有列的大小、精度和可为空值发生变化,它将更改现有列的类型。它不会删除未使用的列来保护数据。

// Migrate the schema
db.AutoMigrate(&Product{})
db.AutoMigrate(&User{}, &Product{}, &Order{})

创建记录

// Create
db.Create(&Product{Code: "D42", Price: 100})

要高效地插入大量记录,请将切片传递给Create方法。GORM将生成一个SQL语句来插入所有数据和回填主键值,也将调用hook方法

var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}} 
db.Create(&users)

GORM提供First、Take、Last方法从数据库中检索单个对象,在查询数据库时添加LIMIT 1条件,如果没有找到记录,则返回错误ErrRecordNotFound。

// Read
var product Product
db.First(&product, 1)                 // find product with integer primary key
db.First(&product, "code = ?", "D42") // find product with code D42
// Get the first record ordered by primary key 
db.First(&user) 
// SELECT * FROM users ORDER BY id LIMIT 1;  
// Get one record, no specified order 
db.Take(&user) 
// SELECT * FROM users LIMIT 1;  
// Get last record, ordered by primary key desc 
db.Last(&user) 
// SELECT * FROM users ORDER BY id DESC LIMIT 1;  
result := db.First(&user) 
result.RowsAffected 
// returns count of records found 
result.Error        
// returns error or nil  
// check error ErrRecordNotFound 
errors.Is(result.Error, gorm.ErrRecordNotFound)

如果要避免ErrRecordNotFound错误,可以像db.Limit(1).Find(&user)一样使用Find。Find方法同时接受结构和切片数据

First和Last方法将按主键顺序分别查找第一条和最后一条记录。只有当指向目标结构的指针作为参数传递给方法时,或者当使用db.model()指定模型时,它们才有效。此外,如果没有为相关模型定义主键,则模型将按第一个字段排序。例如:

var user User
var users []User

// works because destination struct is passed in
db.First(&user)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1

// works because model is specified using `db.Model()`
result := map[string]interface{}{}
db.Model(&User{}).First(&result)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1

// doesn't work
result := map[string]interface{}{}
db.Table("users").First(&result)

// works with Take
result := map[string]interface{}{}
db.Table("users").Take(&result)

// no primary key defined, results will be ordered by first field (i.e., `Code`)
type Language struct {
   Code string
   Name string
}
db.First(&Language{})
// SELECT * FROM `languages` ORDER BY `languages`.`code` LIMIT 1