gorm理解 | 青训营笔记

101 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记. gorm的设计是对mysql语句的简化

常规的go-mysql操作

安装

go get github.com/go-sql-driver/mysql

建表

CREATE TABLE `user_info` (
    `uid` INT(10) NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(64) NULL DEFAULT NULL,
    `departname` VARCHAR(64) NULL DEFAULT NULL,
    `created` DATE NULL DEFAULT NULL,
    PRIMARY KEY (`uid`)
);

访问数据库

func main() {
        db, err := sql.Open("mysql",
                "user:password@tcp(127.0.0.1:3306)/douyin")
        if err != nil {
                log.Fatal(err)
        }
        defer db.Close()
}

CRUD

// 插入数据
    stmt, err := db.Prepare("INSERT user_info SET username=?,departname=?,created=?")
    checkErr(err)
    res, err := stmt.Exec("test", " 研发部门", "2017-12-09")
    checkErr(err)
    id, err := res.LastInsertId()
    checkErr(err)
    fmt.Println(id)
	
    // 更新数据
    stmt, err = db.Prepare("update user_info set username=? where uid=?")
	checkErr(err)
	res, err = stmt.Exec("test", id)
	checkErr(err)
	affect, err := res.RowsAffected()
	checkErr(err)
	fmt.Println(affect)
	
	// 查询数据
	rows, err := db.Query("SELECT * FROM user_info")
	checkErr(err)
	for rows.Next() {
		 var uid int
		 var username string
		 var department string
		 var created string
		 err = rows.Scan(&uid, &username, &department, &created)
		 checkErr(err)
		 fmt.Println(uid)
		 fmt.Println(username)
		 fmt.Println(department)
		 fmt.Println(created)
	}
	
	// 删除数据
	stmt, err = db.Prepare("delete from user_info where uid=?")
	checkErr(err)
	    //res, err = stmt.Exec(id)
    checkErr(err)
    affect, err = res.RowsAffected()
    checkErr(err)
    fmt.Println(affect)
    db.Close()

gorm

《GORM 中文文档》 | Go 技术论坛 (learnku.com)

安装

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

快速入门

package main

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

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

func main() {
  db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }

  // 迁移 schema
  db.AutoMigrate(&Product{})

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

  // Read
  var product Product
  db.First(&product, 1) // 根据整形主键查找
  db.First(&product, "code = ?", "D42") // 查找 code 字段值为 D42 的记录

  // Update - 将 product 的 price 更新为 200
  db.Model(&product).Update("Price", 200)
  // Update - 更新多个字段
  db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // 仅更新非零值字段
  db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

  // Delete - 删除 product
  db.Delete(&product, 1)
}

就拿抖音的项目来说,我们设计的表如图所示

type UserInfo struct {
	gorm.Model
	Id            int64  `gorm:"primaryKey"`
	Name          string `gorm:"varchar(50);not null;unique"`
	Password      string `gorm:"varchar(50);not null"`
	FollowCount   int64
	FollowerCount int64
	IsFollow      bool `json:"is_follow,omitempty"`
	Token         string
}

gorm连接mysql

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

func main() {
  // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  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{})
}

课中课程的结构主要分为如下部分:

  • 理解 Database/SQL

    • Database/SQL 的基本用法
    • 设计原理
    • 基础概念
  • GORM 的使用简介

    • GORM 的基本用法
    • Model 定义
    • 惯例约定
    • 关联介绍
  • GORM 的设计原理

    • SQL 生成的机制
    • 插件扩展机制
    • ConnPool 扩展机制
    • Dialector 扩展机制
  • GORM 最佳实践

    • GORM 最佳时间
    • 定制企业级开发
  • FAQ & 工程成长