golang基础:性能调优,gin框架操作cookie session以及数据库操作相关 | 青训营笔记

738 阅读1分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第7篇笔记;

性能优化相关

性能优化建议-Benchmark

可以用Benchmark进行性能检测,如下一个例子:

简单示例:

被检测函数:

func tool(s string) string {
   var s1 string = strconv.Itoa(len(s))
   for i := 0; i < 18; i++ {
      s += s1
   }
   return s
}

检测方法:

func BenchmarkMain(b *testing.B) {
   b.ResetTimer()
   defer b.StopTimer()
   for i := 0; i < 6; i++ {
      tool("hello")
   }
}

检测命令:go test -bench="." 结果:

image.png

  1. -bench:后面代表为需要测试的方法。如果是"."则代表执行所有的Benchmark开头的方法。
  2. -benchmem:则代表输出参数中会展示内存的消耗和申请次数。
  3. -count:代表测试次数。

使用要求:

1、检测方法函数所在文件名必须以_test.go结尾:

image.png

2、检测方法名必须以Benchmark开头,并且Benchmark后面的首字母必须大写,并且测试方法必须有参数*testing.B

image.png

3、检测方法和被检测方法的包名都不能是main:

image.png

4、检测方法不能有返回值;

预分配内存

1、尽可能在使用make()初始化切片时提供容量信息;

2、同样不断向map中添加元素会触发map的扩容,最好预先设置好map的容量,例如:data:=make(map[int]int,18)//预设值容量18

字符串处理

image.png

image.png

image.png

使用:

  1. 先声明一个var builder strings.Builder
  2. 初始化容量builder.Grow(len(s) + 18)
  3. 拼接字符串builder.WriteString(string);
  4. 最后结果转化为字符串:builder.String()

空结构体

使用空结构体节省内存,空结构体struce{}实际上不占据任何内容空间,用来做占位符十分合适;

atomic包

image.png

Gin中的Cookie和Session

如果我们要实现多个页面之间共享数据的话我们就可以使用Cookie或者Session实现

Cookie

cookie存储于访问者计算机的浏览器中,可以让我们在同一个浏览器访问同一个域名的时候共享数据; 实现的功能:

  1. 保证用户登陆状态
  2. 保存用户浏览的历史记录
  3. 猜你喜欢,智能推荐
  4. 电商系统加入购物车 创建Cookie方法SetCookie()源码:

image.png httpOnly为false时前端js才能访问;

设置cookie:

//设置cookie
c.SetCookie("username", "张左邻", 3600, "/", "localhost", false, true)

获取cookie:

//获取cookie
username, _ := c.Cookie("username")

删除cookie:只需要将cookie的过期时间设置为-1即可:

//删除cookie
c.SetCookie("username", "张左邻", -1, "/", "localhost", false, true)

多个二级域名共享cookie

例如a.xxx.com设置的cookie可以在b.xxx.com上访问,可以这样设置cookie: c.SetCookie("usrename", "张三", 3600, "/", ".xxx.com", false, true)

Session

session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而session保存在服务器上。

当客户端浏览器第一次访问服务器并发送请求时,服务器端会创建一个 session 对象,生成一个类似于key,value的键值对,然后将value保存到服务器,将key(cookie)返回到浏览器(客户)端。浏览器下次访问时会携带 key(cookie),找到对应的session(value)。

gin使用session

Gin官方没有给我们提供Session相关的文档,这个时候我们可以使用第三方的Session中间件来实现;

Gin GORM连接操作mysql

GORM介绍

GORM是Golang的一个orm框架。简单说,ORM就是通过实例对象的语法,完成关系型数据库的操作的技术,是"对象-关系映射"(Object/Relational Mapping)的缩写。使用ORM框架可以让我们更方便的操作数据库。

GORM官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server [官方文档](GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.)

使用

首先安装GORM:

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

然后引入:

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

查询所有用户(示例)

首先创建一个结构体与表进行绑定:

type User struct {
   //`User`默认绑定的表名是`users`
   Id       int
   Username string
   Age      int
   Email    string
   AddTime  int
}
func (User) TableName() string {
   return "user" //结构体User绑定数据库表user
}

创建结构体注意事项:

  1. 结构体的名称必须首字母大写,并和数据库表名称对应。例如:表名称为user结构体
  2. 名称定义成User,表名称为article_cate结构体名称定义成ArticleCate
  3. 结构体中的字段名称首字母必须大写,并和数据库表中的字段一一对应。例如:下面结构体中的Id和数据库中的id对应,Username和数据库中的username对应,Age和数据库中的age对应,Email和数据库中的email对应,AddTime和数据库中的add_time字段对应
  4. 默认情况表名是结构体名称的复数形式。如果我们的结构体名称定义成User,表示这个模型默认操作的是users表。
  5. 我们可以使用结构体中的自定义方法TableName改变结构体的默认表名称 创建一个初始化方法用来连接数据库并生成连接对象:
var DB *gorm.DB
var err error
func init() {
   dsn := "root:12345ssdlh@tcp(124.70.84.192:3306)/my_db01?charset=utf8mb4&parseTime=True&loc=Local"
   //格式“用户名:密码@tcp(ip号:端口号)/库名....”
   DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
   if err != nil {
      fmt.Println(err)
   }
}

控制器方法在相应的请求路径下内进行查询

func (con UserController) Index(c *gin.Context) {
   userList := []models.User{} //根据结构体创建切片
   models.DB.Find(&userList)//把查到的数据赋值给userList
   c.JSON(200, gin.H{   
      "message": userList,
      "name":    "用户列表",
   })
}

其他操作数据库方法

根据条件查询(age>20):

userList := []models.User{} //根据结构体创建切片
models.DB.Where("age>20").Find(&userList) //查询age>20的用户(写死了)

增加用户:

user := models.User{
   Username: "李静文",
   Age:      20,
   Email:    "hsgyfer@rwt",
   AddTime:  102,
}
models.DB.Create(&user)

更新用户:

//方法1:保存所有字段(修改id=6的数据)
user := models.User{Id: 6}
models.DB.Find(&user)
user.Username = "李文静"
models.DB.Save(&user)
//方法2:更新单列
user := models.User{}
models.DB.Model(&user).Where("id=?", 6).Update("age", 21)
//也可以更新多列,那就是models.DB.Model(&user).Where("id=?", 6).Update(user{xxx:yyy....})

删除用户:

//方法1
user := models.User{Id: 6}
models.DB.Delete(&user)
//方法2
user := models.User{}
models.DB.Where("id=?", 6).Delete(&user)