GORM实践(上)|青训营

97 阅读1分钟

一、前言

本篇文章主要为GORM实践的代码及注释。

二、实践

数据序列化与SQL表达式-SQL表达式更新创建

// 方法一:通过gorm.Expr使用SQL表达式
db.Model(User{}).Create(map[string]interface{}{
  "Name":"jinzhu",
  "Location":gorm.Expr("ST_PointFromText(?)","POINT(100 100)"),
})

db.Model(&product).Update("price",gorm.Expr("price * ? + ?, 2, 100))

// 方法2:使用GORMValuer使用SQL表达式 / SubQuery
type Location struct {
  X, Y int
}
func (loc Location) GormValue(ctx context.Context, db *gorm.DB) clause.Expr {
  return gorm.Expr("ST_PointFromText(?)", fmt.Sprintf("POINT(%d %d)", loc.X, loc.Y))
db.Create(User{Name: "jinzhu", Location: Location{X: 100, Y:100}})

//方法3:通过 *gorm.DB 使用SubQuery
subQuery := db.Model(&Company{}).Select("name").Where("companies.id = users.company_id)
db.Model(&user).Updates(map[string]interface{}{}{"company_name": subQuery})

**批量数据操作-批量创建/查询

// 批量创建
var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}}
db.Create(&users)
db.CreateInBatches(users, 100)
for _, user := range users {
  user.ID
}

// 批量查询
rows, err := db.Model(&User{}).Where("role = ?", "admin").Rows()
for rows.Next()
  // 方法1:sql.Rows Scan
  rows.Scan(&name, &age, &email)
  // 方法2:gorm ScanRows
  db.ScanRows(rows, &user)
}

DB.Where("role = ?", "admin").FindInBatches(&results, 100, func(tx *gorm.DB, batch int) error{})

代码复用、分库分表、Sharding -代码复用

func Paginate(r *http.Request) func(db *gorm.DB) *gorm.DB {
  return func (db *gorm.DB) *gorm.DB {
    page, _ := strconv.Atoi(r.Query("page"))
    if page ==0 {
      page = 1
    }
    
    pageSize, _ :=strconv.Atoi(r.Query("page_size"))
    switch {
    case pageSize > 100:
      pageSize = 100
    case pageSize <= 0:
      pageSize = 10
    }
    
    offset := (page - 1) * pageSize
    return db.Offset(offset).Limit(pageSize)
  }
}

// 代码共享
db.Scopes(Paginate(r)).Find(&users)
db.Scopes(Paginate(r)).Find(&articles)

混沌工程

import (
  "example.com/gorm/sqlchaos"
  "gorm.io/gorm"
)

db, err := gorm.Open(
  mysql.Open(dsn),
  &gorm.Config{},
  sqlchaos.WithChaos(sqlchaos.Config{
    PSM:  "service name",
    DBName: "dbname",
    EnvList: []string{"ppe", "boe"},
  }),
)

db.Create(&User{ID: 1024, Name: "rick", Result: 10})