Go Web学习笔记(五)- 数据库ORM
的今天开始学习数据库操作: database/sql:标准库,偏底层,显示SQL GORM: ORM 开发效率高,适合快速CRUD database/sqldatabase/sql是Go标准库提供的通用SQL数据库接口,需要配合具体数据库driver使用。 安装依赖1go get github.com/go-sql-driver/mysql 创建pkg/db/db.go文件1234567891011121314151617181920212223242526package dbimport ( "database/sql" "log" "time" _ "github.com/go-sql-driver/mysql" // 注意这里,忘记引用的话会报错)func NewDB(dsn string) (*sql.DB, error) { db, err := sql.Open("mysql", dsn) if err != nil { ...
Go Web学习笔记(四)- 项目分层
今天开始学习Gin的项目分层,对于Java程序员来说,这很轻松,但是Go与Java多少有些差异。不过大体上都是通用的。 我将goweb项目的目录做了下归类。将main()里面的路由提取到专门管理路由的包里面。还有业务逻辑、错误处理、DTO等等。目前的项目结构如下: 123456789101112131415goweb/├── go.mod├── main.go├── errs/ // 业务错误│ └── error.go ├── middleware/ // 中间件│ └── handlers.go ├── model/ │ └── user_dto.go // 存放所有用户相关的输入输出结构体├── handler/ // 处理HTTP参数和响应 相当于controller,handler是Go风格,controller是java风格,用哪个都行│ └── user_handler.go├── services/ // 处理业务逻辑 ...
Go Web学习笔记(三)- middleware、认证、日志
今天学习的知识点: Gin middleware c.Next() c.Abort() 日志中间件 认证中间件 JWT基础 把用户信息放进context Gin middlewareGin中间件的底层原理是:责任链与洋葱模型。在Spring MVC中,拦截器(interceptor)依赖的是反射和多层代理,而Go Gin中,中间件的本质是一个函数数组的顺序执行。 Gin的核心数据结构gin.Context中,包含了一个中间件和业务处理函数的切片: 12345type Context struct { // .... handlers HandlersChain // 本质是[]HandlerFunc,即函数切片 index int8 // 当前执行了第几个函数} 当你注册了中间件,并写了业务路由时,Gin会把他们按顺序拼接成一条流水线。例如:[Logger,Auth, TargetBusinessFunc]。 此时index的初始值是-1。 c.Next()Gin中的c.Next()的作用是:继续执行后续...
Go Web学习笔记(二)- JSON binding、validator、错误响应
今天学习: ShouldBindJSON binding tag 参数校验 统一错误响应 业务错误和参数错误区分 ShouldBindJSONShouldBindJSON会把请求body里的JSON绑定到struct 1234567891011121314151617181920212223type CreateUserRequest struct { Name string `json:"name"` Email string `json:"email"` Age int `json:"age"`}func createUser(c *gin.Context) { var req CreateUserRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error()...
Go Web学习笔记(一)- 路由、参数、JSON 响应
今天开始学习Go Web,目前主流的框架有gin、go-zero、echo等。我还是随主流,选择gin。 今天要学习的知识点是: 启动Gin服务 定义Get / POST / PUT / DELETE / 路由 获取路径参数 获取query参数 返回JSON响应 路由分组 创建一个gin项目初始化项目123456# 创建项目目录mkdir gowebcd goweb# 初始化go modego mod init dev.net.cn/goweb 执行完成后,会生成一个go.mod文件,用来管理项目的依赖和版本。 配置代理为了更快的下载Go的模块,这里推荐大陆用户配置代理 12345# 如果是 Linux / macOSexport GOPROXY=https://goproxy.cn,direct# 如果是 Windows (PowerShell)$env:GOPROXY="https://goproxy.cn,direct" 下载gin依赖1go get -u github.com/gin-gonic/gi...
VS Code无法登录微软账号
现象在VS Code中,点击账户->登录以同步设置后,弹出的登陆界面提示404,右下角错误信息为:no_network_connectivity: No network connectivity. Check your internet connection.。如下图所示: 在mac/linux上这个功能是可用的。 解决方案其根本原因是Clash Verge在作祟,但也不能每次都关闭,还要查到具体的原因。后来通过多方搜索,找到了原因: 登录调用的是工作或学校账户的UWP应用,默认无法使用本地回环地址的代理 所以,需要借助Clash Verge自带的UWP 工具,在设置 -> Clash设置 -> UWP 工具。打开后,勾选列表中的工作或学校账户。 点击Save Changes后,再次尝试登录,就可以正常登录了。
Go语言学习笔记(八)- 标准库
文件操作:os、io、bufioGo语言中,文件操作主要分三层 os : 直接和操作系统交互,比如打开文件、删除文件、创建文件、读写文件等。 io :抽象I/O行为,比如:io.Reader、io.Writer、io.Copy bufio : 带缓冲的读写,适合按行读取、大文件处理、减少系统调用。 os.ReadFile一次性读取整个文件,适合读取小文件,例如配置文件、模板文件、JSON文件。 12345678func TestOsReadFile(t *testing.T) { data, err := os.ReadFile("d:/a.txt") if err != nil { t.Error(err) } fmt.Println(string(data))} 注意:不要用它读取特别大的文件,因为会一次性把整个文件加载到内存。 os.WriteFile一次性写入文件 123456789101112func TestOsWriteFile(t *testing.T) { data ...
Go语言学习笔记(七)- 错误处理与包管理
error 接口与 errors 包Go语言的错误,不像Java/Python那样默认靠异常传播机制,而是一个普通返回值。Go内置的error类型本质上是一个接口。只要求实现一个方法Error() string;nil通常表示没有错误。 123type error interface { Error() string} 在Go代码里最常见的模板就是: 1234result,err := doSomething()if err !=nil{ return err} 这种模式,就相当于Java的try/catch。 创建简单错误errors.New(text)会创建一个只包含文本信息的error;每次调用errors.New都返回一个不同的error的值,即使文本相同。 123456789101112131415func divide(a, b int) (int, error) { if b == 0 { return 0, errors.New("division by zero&q...
Go语言学习笔记(六)- 并发编程
今天开始学习Go语言的重要特性,Goroutine。 goroutineGoroutine,通常称之为协程,区别于Java的线程,它是由Go runtime调度,启动成本很低,初始栈很小,并且可以按需增长。多个goroutine在同一个进程地址空间内并发执行。 先看看Java的线程: 1new Thread(() -> {System.out.println("Hello Java");}).start(); 在看看看Go的goroutine: 123go func() { fmt.Println("Hello Go")}() 启动普通函数12345678910111213141516171819202122232425262728import ( "fmt" "sync" "testing")func PrintName(name string) { fmt.Println(name)}func Te...
Go语言学习笔记(五)- 接口与类型系统
接口在Go语言中,接口的设计是一个典型的“鸭子类型”(Duck Typing)。如果一个结构体拥有了某个接口定义的所有方法,那么它就实现了这个接口。 先看看Java的接口(显示实现接口) 123456789interface Animal{ void say();}class Dog implements Animal { public void say(){ System.out.println("wang!") }} 类必须通过implements关键字明确申明自己实现了某个接口。 再看看Go的接口 123456789type Animal interface { Say();}type Dog struct{}func (d Dog) Say(){ fmt.Println("wang!")} Go是隐式实现接口,只要一个类型实现了接口需求的所有方法,就自动认为他实现...

