Gorm实践 | 青训营笔记

119 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记。

1.Gorm基础使用

1.1 知识背景

设计简洁、功能强大、自由扩展的全功能ORM

  • 设计原则:API精简、测试优先、最小惊讶、灵活扩展、无依赖可信赖
  • 功能完善:
    • 关联:一对一、一对多、单表自关联、多态;Preload、 Joins 预加载、级联删除;关联模式;自定义关联表
    • 事务:事务代码块、嵌套事务、Save Point
    • 多数据库、读写分离、命名参数、Map、子查询、分组条件、代码共享、SQL表达式(查询、创建、更新)、自动选字段、查询优化器
    • 字段权限、软删除、批量数据处理、Prepared Stmt、自定义类型、命名策略、虚拟字段、自动track时间、SQL Builder、Logger
    • 代码生成、复合主键、Constraint、 Prometheus、 Auto Migration、真 跨数据库兼容...
    • 多模式灵活自由扩展
    • Developer Friendly

1.2 安装Gorm

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

1.3模型定义-惯例约定

约定优于配置

  • 表名为struct name的snake_ cases复数格式
  • 字段名为field name的snake_ case单数格式
  • ID/ ld字段为主键,如果为数字,则为自增主键
  • CreatedAt字段,创建时,保存当前时间
  • UpdatedAt字段,创建、更新时,保存当前时间
  • gorm.DeletedAt字段,默认开启soft delete模式

一切皆可配置:gorm.io/docs/conven…

1.4 Gorm基本用法

package main

import (
 "database/sql"
 _ "github.com/go-sql-driver/mysql"

)

func main() {
 db, err := sql.Open ("mysqL", "user:password@tcp(127.0.0.1:3306])/hello")
 rows, err := db.Query("select id, name from users where id = ?", 1)
 if err == nil {
  //......
 }
 defer rows.Close()
 var users []User
 for rows.Next() {
  var user User
  err := rows.Scan(&user. ID, &user,Name)
  if err!=nil{
  //..
  }
 }
  users = append(users, user)
  if rows.Err() != nil {
  }
}

DSN是什么?

参考:github.com/go-sql-driv…

1.5 CRUD

package main

// gorm demo1

import (
 "fmt"
 "github.com/jinzhu/gorm"
 _ "github.com/jinzhu/gorm/dialects/mysql"
)

// UserInfo --> 数据表
type UserInfo struct {
 ID     uint
 Name   string
 Gender string
 Hobby  string
}

func main() {
 // 连接MySQL数据库
 db, err := gorm.Open("mysql", "root:root@(127.0.0.1:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
 if err != nil {
  panic(err)
 }
 defer db.Close()

 // 创建表 自动迁移(把结构体和数据表进行对应)
 db.AutoMigrate(&UserInfo{})

 // 创建数据行
 //u1 := UserInfo{1, "baiai", "男", "呱~"}
 //db.Create(&u1)
 // 查询
 var u UserInfo
 db.First(&u) // 查询表中第一天数据保存到u中
 fmt.Printf("u:%#v\n", u)
 // 更新
 db.Model(&u).Update("hobby", "双色球")
 // 删除
 db.Delete(&u)
}

1.6 关联

// Video中关联了User
type Video struct {
    Id            int64  `json:"id,omitempty"              gorm:"primaryKey; type:bigint(20) AUTO_INCREMENT"`
    UserId        int64  `json:"-"                         gorm:"type:bigint(20)  NOT NULL"`
    Author        User   `json:"author"                    gorm:"foreignKey:UserId"`
    PlayUrl       string `json:"play_url,omitempty"        gorm:"type:varchar(255) NOT NULL"`
    CoverUrl      string `json:"cover_url,omitempty"       gorm:"type:varchar(255) NOT NULL"`
    FavoriteCount int64  `json:"favorite_count,omitempty"  gorm:"type:int  NOT NULL DEFAULT 0"`
    CommentCount  int64  `json:"comment_count,omitempty"   gorm:"type:int  NOT NULL DEFAULT 0"`
    IsFavorite    bool   `json:"is_favorite,omitempty"     gorm:"-"`
    Title         string `json:"title,omitempty"           gorm:"type:varchar(255)  collate utf8mb4_general_ci NOT NULL DEFAULT ''  "`
    CreatedAt     time.Time
    UpdatedAt     time.Time
}

type User struct {
    Id            int64  `json:"id,omitempty"             gorm:"primaryKey; type:bigint(20) AUTO_INCREMENT;"`
    Name          string `json:"name,omitempty"           gorm:"uniqueIndex:idx_name; type:varchar(64) UNIQUE collate utf8mb4_general_ci not null" `
    FollowCount   int64  `json:"follow_count,omitempty"   gorm:"column:follow_count; type:INT NOT NULL DEFAULT 0 "`
    FollowerCount int64  `json:"follower_count,omitempty" gorm:"column:follower_count; type:INT NOT NULL DEFAULT 0"`
    Password      string `json:"-"                        gorm:"column:password; type:varchar(200) NOT NULL"`
    IsFollow      bool   `json:"is_follow,omitempty"      gorm:"-"`
    Salt          string `json:"-"                        gorm:"column:salt;  type:varchar(255) NOT NULL"`
    CreatedAt     time.Time
    UpdatedAt     time.Time
}

1.7 关联操作

ProLoad/Joins预加载

// 查询用户时并找出其订单信息
db.Preload("Orders").Preload("Profile").Find(&users)
// 使用Jion SQL加载(单条JOIN SQl)
db.Joins("Company").Joins("Manager").First(&user,1)
db.Joins("Company",DB.Where(&Company{Alive:true})).Find(&users)

联级删除

// User 中有 Orders []Order
db.AutoMigrate(&User{})
db.Delte(&USer{})

//或者
// 删除user时,也删除user的account
db.Select("Account).Delete(&user)

ConnPool是什么

![9ZRXR0_ZJ(LL{EFMIS~%PN.png

Gorm最佳实践

数据序列化与SQL表达式 批量数据操作 代码复用、分库分表、Sharding 混沌工程/压测 Logger/ Trace Migrator Gen代码生成/ Raw SQL 安全