GORM基础与概念 | 青训营笔记

107 阅读3分钟

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

前言

今天对GO语言与数据库交互的部分进行了学习,因为没有学习并实现过数据库交互的,所以还是有一些吃力的。

一、本堂课重点内容

  1. 理解database/sql包的基本用法,设计原理,基础概念。
  2. GORM的基本用法,Model定义,惯例约定,关联介绍
  3. GORM设计原理:SQL生成,扩展机制,ConnPool,Dialector
  4. GORM实践

二、详细知识点介绍:

database/sql包

导入
import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)
基本用法

连接DB: sql.Open()
示例:

db,err :=sql:Open("mysql","user:password@tcp(127.0.0.1:3306)/helo")

sql.Open的第一个参数是driver名称,第二个参数是driver连接数据库的信息,各个driver可能不同。DB不是连接,并且只有当需要使用时才会创建连接
读取DB: db.Query()
示例:

rows,err := db.Query("select id,anme from users where id = ?",1)

db.Query()表示向数据库发送一个query

设计原理

image.png

GORM基础

模型定义
type User struct {   
ID           uint   
Name         string   
Email        *string   
Age          uint8   
Birthday     *time.Time   
MemberNumber sql.NullString   
ActivatedAt  sql.NullTime   
CreatedAt    time.Time   
UpdatedAt    time.Time 
}
惯例约定

约定优于配置

  • 表名为struct name的snake_cases复数格式
  • 字段名为field name的snake_case单数格式
  • ID/id字段为主键,如果为数字,则为自增主键
  • CreatedAt字段,创建时,保存当前时间
  • UpdateAt字段,创建、更新时,保存当前时间
  • gorm.DeletedAt字段,默认开启soft delete模式
创建记录
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}

result := db.Create(&user) // pass pointer of data to Create

user.ID             // returns inserted data's primary key
result.Error        // returns error
result.RowsAffected // returns inserted records count
使用所选字段创建记录

创建一条记录并为指定的字段赋值

db.Select("Name", "Age", "CreatedAt").Create(&user) // INSERT INTO `users` (`name`,`age`,`created_at`) VALUES ("jinzhu", 18, "2020-07-04 11:05:21.775") 

创建一个记录,忽略传递给省略的字段的值 db.Omit("Name", "Age", "CreatedAt").Create(&user)
// INSERT INTO users (birthday,updated_at) VALUES ("2020-01-01 00:00:00.000", "2020-07-04 11:05:21.775")

检索单个对象
// 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)
更新单列
// Update with conditions  
db.Model(&User{}).Where("active = ?", true).Update("name", "hello")  
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true;  
  
// User's ID is `111`:  
db.Model(&user).Update("name", "hello")  
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;  
  
// Update with conditions and model value  
db.Model(&user).Where("active = ?", true).Update("name", "hello")  
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
删除一个记录
// Email's ID is `10` db.Delete(&email) // DELETE from emails where id = 10;  // Delete with additional conditions db.Where("name = ?", "jinzhu").Delete(&email) // DELETE from emails where id = 10 AND name = "jinzhu"; 
SQL是怎样生成的

image.png

image.png

image.png

image.png

插件是怎样工作的

image.png

image.png

image.png

image.png

image.png

ConnPool是什么

image.png

image.png

Dialector是什么

image.png

三、实践练习例子:

首先,通过数据序列化与SQL表达式入手,再实现批量数据操作,紧接着是代码复用、分库分表。然后又通过示例帮助我们理解混沌工程。接下来又实践了数据库迁移和Gen代码生成,最后又通过示例去理解安全问题例如SQL注入。

四、课后个人总结:

今天所学内容对个人来讲有一些难度,尤其是到了后面的实践环节,是有一些云里雾里的感觉,甚至觉得自己之前数据库白学了。主要原因还是课前预习没做好。

五、引用参考:

Go语言database/sql包--学习笔记_一只IT小小鸟的博客-CSDN博客
go-sql-driver/mysql: Go MySQL Driver is a MySQL driver for Go's (golang) database/sql package (github.com)
GORM - The fantastic ORM library for Golang, aims to be developer friendly.