这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
前言
今天对GO语言与数据库交互的部分进行了学习,因为没有学习并实现过数据库交互的,所以还是有一些吃力的。
一、本堂课重点内容
- 理解database/sql包的基本用法,设计原理,基础概念。
- GORM的基本用法,Model定义,惯例约定,关联介绍
- GORM设计原理:SQL生成,扩展机制,ConnPool,Dialector
- 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
设计原理
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是怎样生成的
插件是怎样工作的
ConnPool是什么
Dialector是什么
三、实践练习例子:
首先,通过数据序列化与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.