- Go三件套:
Gorm1)快速入门:2)支持的数据库:3)CRUD:* 新增数据:* 查询数据:* 更新数据:* 删除数据:软删除(逻辑删除)4)GORM事务:5)GORM Hook(类似前后通知):6)性能提高:GORM配置7)扩展生态:
Gorm
1)快速入门:
- 注意:天然支持sql注入
- 注意:图右为Gorm的约定,比如结构体如果定义ID变量会被默认为主键
2)支持的数据库:
3)CRUD:
* 新增数据:
- 右上:当存在唯一索引(如id),那么指定为不处理冲突,则create()执行update()更新操作
* 查询数据:
* 更新数据:
* 删除数据:软删除(逻辑删除)
4)GORM事务:
- 简单实现:
- 推荐方法:Transaction
5)GORM Hook(类似前后通知):
- hook操作会带有默认事务
6)性能提高:GORM配置
7)扩展生态:
补充:Golang基础语法
- Go语言基础
一、介绍Go二、基础语法基本格式、编译运行的命令:变量:if else:后面没有括号循环:只有for循环switch case:数组:切片:map:range:函数:指针:修改变量的值结构体:结构体方法:错误处理:error类型,返回值传递,if处理字符串操作:“strings”包打印:“fmt”包,格式字符json操作:“encoding/json”包时间处理:“time”包数字解析:“strconv”包进程信息:“os”、“os/exec”包defer:函数返回前被调用,从后往前三、实战1)猜谜游戏:2)在线词典:* 需求:* 实现:3)实现SOCKS5代理:* 小demo:四、语言进阶 - 协程1)协程:Goroutine2)协程间通信:channel3)WaitGroup:协程计算器五、依赖管理1)Go Module介绍:2)go.mod组成:3)依赖关系冲突:选择最低的兼容版本4)依赖分发:Proxy5)go get工具、go mod工具:六、测试1)单元测试:2)Mock3)基准测试:七、项目1)准备:2)查询:
一、介绍Go
二、基础语法
基本格式、编译运行的命令:
变量:
if else:后面没有括号
- 括号也可以有,编译的时候会去掉
循环:只有for循环
switch case:
数组:
切片:
map:
range:
函数:
指针:修改变量的值
- 不以指针传入的变量只是拷贝,需要修改值时要传入指针
结构体:
- 同样有结构体指针,可对属性进行修改,且有时能避免一些大结构体拷贝的开销
结构体方法:
错误处理:error类型,返回值传递,if处理
- 不同于java的异常,go用返回值代表错误,用if else处理错误
字符串操作:“strings”包
- 注意一个中文会对应多个字符
打印:“fmt”包,格式字符
json操作:“encoding/json”包
时间处理:“time”包
数字解析:“strconv”包
进程信息:“os”、“os/exec”包
defer:函数返回前被调用,从后往前
三、实战
1)猜谜游戏:
- 一、生成随机数:注意需要设置随机数种子(时间),不然每次运行都是相同的数字
- 二、用户输入:用”bufio”包下方法来读取用户输入
- Ps:后面可以通过scanf更快的读取
- 三、判断:
- 四、完整实现:
2)在线词典:
* 需求:
- 运行该方法时,传入单词,方法打印该单词的音标、含义等
- 考点:需要发送http请求,解析json字符串、代码生成等
* 实现:
- 一、抓包:在网页中看请求
- 二、复制请求的curl命令:
- 三、打开代码生成网址:转换为go语言的请求
- 由于header比较复杂,少部分代码可能发生编译错误,直接删掉
- Ps:看看生成的代码(输入为good的情况)
- 四、改为变量输入(输入不固定):上面代码生成能看出request body的结构,直接创建对应的结构体对象,通过json序列化并转换为byte数组来当作newRequest的参数
- 五、解析response body,更好的打印出人能看的结果:
- 和request body一样,最好是写一个对应的结构体,然后后面打印这个返回结果(response body)的一些属性
- 方法:打开代码生成网站,将抓包的response body的json字符串传进去,就能生成对应的go的结构体
- 用生成的结构体获取到返回的response body数据,反序列化并直接打印:
- 六、将打印内容改为需求中需要打印的信息
- 七、获取该进程(main方法)的变量,取第二个作为参数word,传入打印方法
3)实现SOCKS5代理:
* 小demo:
- 需求:创建一个基于tcp连接的服务(本机的xxx端口),读取用户端发送的报文(如字符串),返回相同的字符串
- 重点:怎么实现tcp端口,开放并获取请求的字符串,并处理和打印出来
四、语言进阶 - 协程
1)协程:Goroutine
- 并发:一个核,多线程抢夺时间片
- 并行:多个核,多线程一起运行 -> Go能充分发挥多核优势
- 线程:属于内核态,系统级别,它的创建等操作会重很多
- 协程(Goroutine):属于用户态,它由go创建和调度,操作轻(轻松应对上万协程)
- 方法:通过在函数前加上go关键字来为函数创建协程
2)协程间通信:channel
- CSP:通信与共享内存
- Go提倡通过通道来共享内存
- 无缓冲通道:直接传
- 有缓冲通道:规定队列中的元素数量,满了会有阻塞
- 通过通道共享内存的具体实现:
- 补充(不推荐):通过加锁实现并发的安全
3)WaitGroup:协程计算器
- 前面介绍协程用到的sleep不够优雅(可能出错),可以用WaitGroup更加精确的停止
- 代码:
五、依赖管理
1)Go Module介绍:
2)go.mod组成:
- ①go.mod的版本规则:
- ②直接依赖、间接依赖:
- ③incompatible:没有go.mod文件且主版本2+的依赖会有该后缀(表示可能有些代码不兼容)
3)依赖关系冲突:选择最低的兼容版本
4)依赖分发:Proxy
- 通过代理仓库来获取依赖:修改GOPROXY变量实现
5)go get工具、go mod工具:
六、测试
1)单元测试:
- 一、组成:
- 二、规则:
- Ps:如果测试方法不以大写Test开头,ide就不会出现运行的按钮提示
- 例:
- 结果:
- 三、使用第三方assert包进行校验
- 四、覆盖率
- 提高覆盖率:
- tips:代码设计时,函数应单一职责,这使得测试的单元粒度小,而覆盖率会更高
2)Mock
- 一、单元测试的要求
- 幂等:每次运行的结果应该一样
- 稳定:单元测试应该是相互隔离的,我们在任何时候都能运行
- 而一些复杂的依赖,比如数据库、cache等,由于网络等因素会造成一些问题 -> Mock机制
- 例:一些问题
- 函数依赖于一些本地的文件,一旦文件被修改,就不能正常地测试了
- 一、介绍mock包:monkey
- 打桩:
- 例:用Patch()打桩函数ReadFirstLine(),修改逻辑为直接返回值“line110”
3)基准测试:
- 概念:指测试代码的运行性能、cpu损耗等
- 例:
- 扩展:解决rand包性能差问题,介绍一个开源fastrand(适用大部分场景)
七、项目
1)准备:
- 分层模型:
- web项目组件:
2)查询:
- Ps:这里数据存储在本地文件