这是我参与「第五届青训营 」笔记创作活动的第4天。
引言
今天的课程是关于Go语言的三个框架学习和项目实战,框架分别为Gorm(ORM框架)、Kitex(RPC框架)和Hertz(HTTP框架)。这篇文章主要是针对今天课程的记录和总结。
一、本堂课重点内容
本堂课的知识点
- Gorm:ORM框架,程序员无需直接编写原生SQL语句,框架采用了数据库连接池
- Kitex;微服务RPC框架
- Hertz(HTTP框架),性能远高于Gin
- 项目实战
二、详细知识点介绍
1. Gorm
下载安装
go get -u gorm.io/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:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}
Model
在代码中定义模型(Model)与数据库中的数据表进行映射,在GORM中模型(Models)通常是正常定义的结构体、基本的go类型或它们的指针。
gorm.Model是 gorm中内置定义的一个结构体,包含了一些通用字段
// gorm.Model 的定义
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
CRUD操作
//定义模型
type User struct {
ID int64
Name string
Age int64
CreatedAt time.Time
}
1️⃣增加操作(Create)
func main() {
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
defer db.Close()
//插入一条数据
user := User{Name: "q1mi", Age: 18,CreatedAt:time.Now()}
db.NewRecord(user) // 主键为空返回`true`
db.Create(&user) // 创建user
db.NewRecord(user) // 创建`user`后返回`false`
//指定字段进行插入
db.Select("Name", "Age", "CreatedAt").Create(&user)
// INSERT INTO `users` (`name`,`age`,`created_at`) VALUES ("jinzhu", 18, "2020-07-04 11:05:21.775")
}
插入多条数据,要利用切片
var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}}
db.Create(&users)
for _, user := range users {
user.ID // 1,2,3
}
2️⃣查询操作 (Retrieve)
// Get first matched record
db.Where("name = ?", "jinzhu").First(&user)
// SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;
// IN
db.Where("name IN ?", []string{"jinzhu", "jinzhu 2"}).Find(&users)
// SELECT * FROM users WHERE name IN ('jinzhu','jinzhu 2');
// AND
db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)
// SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22;
// 利用map
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;
注意:当通过结构体进行查询时,GORM将会只通过非零值字段查询,这意味着如果你的字段值为0,'',false或者其他零值时,将不会被用于构建查询条件,解决方法利用map进行零值字段查询,例如:
db.Where(&User{Name: "jinzhu", Age: 0}).Find(&users) //这种查询是失败的
// SELECT * FROM users WHERE name = "jinzhu";
//可以利用map
db.Where(map[string]interface{}{"Name": "jinzhu", "Age": 0}).Find(&users)
3️⃣修改操作(Update)
// 条件更新
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 的 ID 是 `111`
db.Model(&user{111}).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
// 根据条件和 model 的值进行更新
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;
//更新多列属性
// 根据 `struct` 更新属性,只会更新非零值的字段
db.Model(&user).Updates(User{Name: "hello", Age: 18, Active: false})
// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;
// 根据 `map` 更新属性
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})
// UPDATE users SET name='hello', age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
当没有利用Where方法(没有其他的条件时,避免全局更新),Model中的user还会作为条件 若有Where方法时(有其他筛选条件),Model中的user只是用于传递表名称
4️⃣删除操作(Delete)
注意: 删除记录时,请确保主键字段有值,GORM 会通过主键去删除记录,如果主键为空,GORM 会删除该 model 的所有记录。
// 删除现有记录
db.Delete(&email)
//// DELETE from emails where id=10;
// 带额外条件的删除
db.Where("name = ?", "jinzhu").Delete(&email)
// DELETE from emails where id = 10 AND name = "jinzhu";
2. Kitex
待补充
3. Hertz
由字节跳动开源的高性能的Go HTTP框架,作用类别Gin框架,但Hertz的性能更好
下载:
go install github.com/cloudwego/hertz/cmd/hz@latest
路由学习
package main
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
func main(){
h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
h.StaticFS("/", &app.FS{Root: "./", GenerateIndexPages: true})
h.GET("/get", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "get")
})
h.POST("/post", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "post")
})
h.PUT("/put", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "put")
})
h.DELETE("/delete", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "delete")
})
h.PATCH("/patch", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "patch")
})
h.HEAD("/head", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "head")
})
h.OPTIONS("/options", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "options")
})
h.Any("/ping_any", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "any")
})
h.Handle("LOAD","/load", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "load")
})
h.Spin()
}
支持路由组,路由前缀相同的,设计为一组
package main
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
func main(){
h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
v1 := h.Group("/v1")
// 127.0.0.1:8080/v1/get
v1.GET("/get", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "get")
})
v1.POST("/post", func(ctx context.Context, c *app.RequestContext) {
c.String(consts.StatusOK, "post")
})
h.Spin()
}
三、实践练习例子
笔记项目 地址:kitex-examples/bizdemo/easy_note at main · cloudwego/kitex-examples (github.com)
待补充
四、课后个人总结
今天这堂课程学习了三个Go语言进行后端开发可以使用到的框架,因为之前是先学习的Java,Java进行后端开发的框架也进行过学习,将两种语言的框架以功能进行对应:Gorm对应MyBatis、Kitex对应SpringCloud、Hertz对应SpringMVC,当然这种对应并不严谨。
五、引用参考
[1] 青训营课程资料
[2] Go语言中文网
[3] GORM - 中文文档