Echo 项目是一个功能强大且用途广泛的 Web 框架,用于使用 Go 编程语言构建可扩展且高性能的 Web 应用程序。它遵循简单性、灵活性和性能的原则,为开发人员提供了一个高效的工具包,用于构建强大的 Web 应用程序。
资源 系列教程
polarisxu.studygolang.com/posts/go/ec…
Bind
是 Echo 框架提供的一个方法,用于将请求中的数据绑定到指定的结构体实例上。它支持多种数据格式,包括 JSON、XML、表单数据等。
以下是 Bind
方法的一些关键点:
application/json
,Bind
会尝试将请求体中的 JSON 数据解析并绑定到指定的结构体实例上。application/x-www-form-urlencoded
或 multipart/form-data
,Bind
会尝试将请求中的表单数据解析并绑定到指定的结构体实例上。Bind
还可以将查询参数绑定到结构体实例上,但需要结构体字段带有 form
标签,例如 form:"name"
。Bind
也可以将路径参数绑定到结构体实例上,但需要结构体字段带有 param
标签,例如 param:"id"
。初始化项目:
创建一个项目文件并进去
$ mkdir myapp && cd myapp
这将会在你项目的根目录中创建一个go.mod
文件
$ go mod init myapp
接着安装Echo
$go get -u github.com/labstack/echo/v4
创建一个main文件
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}
在终端上,进入到正确目录中 输入
$ go run main.go
看到这个就说明成功启动了, 然后访问http://localhost:1323/
,就会看到映入眼帘的Hello, World!
这几个字眼.
上方文件的代码, 我们等下去解释.
Air 是一个为 Go 项目提供自动重载功能的工具。通过监听项目中文件的变化,自动重新编译并运行你的应用,从而达到热重载的效果,极大地提升开发效率。
安装下载:
go get github.com/air-verse/air@latest
安装好之后, 在项目根目录下创建一个和.air.toml
的配置文件(如果项目中没有这个文件,Air 会使用默认配置)来监听文件变化。一旦检测到文件更改,Air 会自动编译并重启你的应用。
配置内容如下: (可参考)
# .air.toml
# 设置项目根目录
root = "."
# [build] 部分用于定义编译命令和其他编译选项
[build]
cmd = "go build -o main.exe ." # Windows 上生成 .exe 文件
bin = "main.exe" # 指定生成的 .exe 文件名称
include = ["*.go", "config/**/*.yaml"] # 监视的文件变化
exclude = ["vendor/**", "node_modules/**"] # 不监视的文件或目录
# [run] 部分用于定义运行命令和环境变量
[run]
cmd = "./main.exe" # 指定运行的可执行文件
env = ["PORT=8080"] # 设置运行时的环境变量
# [watch] 部分用于定义监视的文件和目录
[watch]
include = ["*.go"]
exclude = ["vendor/**", "node_modules/**"]
# [logger] 部分用于定义日志级别
[logger]
level = "info"
打开终端, 在项目的根目录中运行
air
这就表示项目成功启动了.
gorm : go中较流行的ORM库.
以下是官网描述的特性:
安装:
go get -u gorm.io/gorm
接着去下载安装mysql驱动
go get gorm.io/driver/mysql
我们将连接mysql 的 DSN 存入在.env 环境变量当中.
DSN(DataSourceName)是用于标识和定位数据库的字符串,包含数据库类型、主机、端口等信息。它通过驱动程序解析,建立与数据库的连接,提供了一种标准化的连接方式,增强了应用程序的灵活性和可移植性。
DSN=用户名:密码@tcp(127.0.0.1:3306)/数据库
然后在main文件中,进行加载环境变量
, 读取环境变量
, grom mysql连接
等等
func main() {
// 加载环境变量
loadEnv()
// 初始化数据库连接
initDataBases()
// 启动 HTTP 服务器
startServer()
}
加载环境变量
func loadEnv() {
env := os.Getenv("ENV")
fmt.Println("环境变量", env)
if env != "production" { // 生产环境是用docker运行的,会用--env-file参数指定.env文件,不需要手动加载
err := godotenv.Load()
if err != nil {
log.Fatalf("Error loading .env file: %v", err)
}
}
}
初始化数据库连接
func initDataBases() {
// 获取.env的DSN变量
dsn := os.Getenv("DSN")
fmt.Println("dsn", dsn)
// 调用 Open 方法,传入驱动名和连接字符串
var err error
db.DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
// 检查是否有错误
if err != nil {
fmt.Println("连接数据库失败:", err)
return
}
// 打印成功信息
fmt.Println("连接数据库成功", db.DB)
}
启动服务器
func startServer() {
// 初始化 Echo 实例
e := echo.New()
// 启动服务器
e.Logger.Fatal(e.Start(":8080"))
}
看到这个就说明数据库成功连接了.
接下来,我们继续完善我们的项目的目录搭建工作
my-go-project/
|-- cmd/ # 应用程序的启动点
| |-- main.go # 主入口文件
|-- config/ # 配置文件
| |-- database.go # 数据库配置
| |-- server.go # 服务器配置
| |-- env.example # 环境变量示例文件
|-- db/ # 数据库相关文件
| |-- migrations/ # 数据库迁移文件
| | |-- 20230801_create_users_table.go
| | |-- 20230802_add_roles_to_users_table.go
|-- |models/ # 数据库模型
| | |-- user.go # 用户模型
| | |-- role.go # 角色模型
| |repositories/ # 数据访问层 (DAL)
| | |-- user.go # 用户数据访问层
| | |-- role.go # 角色数据访问层
|-- handlers/ # HTTP 请求处理器
| |-- user.go # 用户请求处理器
| |-- role.go # 角色请求处理器
|-- middleware/ # 中间件
| |-- auth.go # 认证中间件
| |-- logging.go # 日志记录中间件
|-- routes/ # 路由配置
| |-- user.go # 用户路由
| |-- role.go # 角色路由
|-- services/ # 业务逻辑层
| |-- user.go # 用户服务
| |-- role.go # 角色服务
|-- utils/ # 辅助函数和工具
| |-- jwt.go # JWT 工具
| |-- validators.go # 验证工具
|-- internal/ # 内部模块或包
| |-- ...
|-- static/ # 静态文件
|-- templates/ # 模板文件
|-- go.mod # Go 模块元数据
|-- go.sum # Go 模块校验和
|-- .gitignore # Git 忽略文件列表
|-- .env # 环境变量文件
|-- .dockerignore # Docker 忽略文件列表
|-- Dockerfile # Docker 镜像构建文件
|-- Makefile # 自动化任务管理文件
|-- README.md # 项目说明文件
|-- LICENSE # 许可证文件
我们先这样分好目录. 方便我们之后的代码开发.
model
: 包含数据模型和它们的相关操作。这些模型通常对应于数据库中的表,并使用 Gorm 提供的方法进行 CRUD
操作。dal
: 数据访问对象(DAO)
层,负责执行实际的数据库操作。DAO 类似于传统的 Repository,它封装了数据库操作,使得模型和业务逻辑层不需要直接与数据库打交道。service
: 业务逻辑层,它调用 DAO 层的方法来获取或修改数据
。业务逻辑层是应用程序的核心部分
,它定义了应用程序的行为和规则。handler
: HTTP 请求处理器,它们处理来自客户端的请求,调用服务层的方法获取所需的数据,并返回适当的响应
。各层之间的一般交互流程:
首先我们在model文件夹下方新建一个user.go的文件
如果数据库中还没有我们需要的表,我们可以使用 gorm 的 AutoMigrate
方法来自动创建表。这个方法会根据我们的模型来生成对应的 SQL 语句,并执行它。
package model
import "time"
// 定义一个User 结构体,用来表示user表
// User 结构体表示用户表
type User struct {
ID uint `gorm:"primaryKey;autoIncrement"` // 主键,自动递增
Name string `gorm:"size:10;not null"` // 用户名,最大长度10,不能为空
Email string `gorm:"unique;size:20;not null"` // 邮箱,唯一索引,最大长度20,不能为空
Password string `gorm:"size:18; not null"` // 密码,不能为空
CreatedAt time.Time `gorm:"autoCreateTime;"` // 在创建时,如果该字段值为零值,则使用当前时间填充
UpdatedAt time.Time `gorm:"autoUpdateTime;"` // 在创建时该字段值为零值或者在更新时,使用当前时间戳秒数填充
}
在db文件夹下的db文件中, 新增一个方法
package db
import (
"fmt"
"gorm.io/gorm"
"quick-start/model"
)
var DB *gorm.DB
// 自动迁移
func AutoMigrate() {
err := DB.AutoMigrate(&model.User{})
if err != nil {
fmt.Println("创建表失败", err)
panic(err)
return
}
fmt.Println("创建表成功")
}
然后再去main.go文件中去使用
func main() {
// 加载环境变量
loadEnv()
// 初始化数据库连接
initDataBases()
db.AutoMigrate()
// 启动 HTTP 服务器
startServer()
}
本部分的主要内容及时获取解析前端传过来的参数,然后传递给
service层
去进行操作. 最后由handle层将数据进行响应返回
新建一个user_handle.go
文件
package handle
import (
"fmt"
"github.com/labstack/echo/v4"
"net/http"
"quick-start/model"
"quick-start/service"
)
// 定义一个UserHandler结构体
type UserHandler struct {
UserService service.UserService
}
// POST 创建一个user 用户
func (h *UserHandler) Create(c echo.Context) error {
name := c.FormValue("name")
email := c.FormValue("email")
password := c.FormValue("password")
fmt.Println("111111111111111")
fmt.Println(name, email, password)
// 三者都不能为空,
if name == "" || email == "" || password == "" {
return c.JSON(http.StatusNotFound, "参数不全")
}
// 创建 User 模型实例
user := &model.User{
Name: name,
Email: email,
Password: password,
}
err := h.UserService.Create(user)
if err != nil {
return c.JSON(http.StatusInternalServerError, err)
}
return c.JSON(http.StatusOK, "创建成功")
}
package service
import (
"quick-start/db"
"quick-start/model"
)
type UserService struct {
}
// 调取数据库,向数据库插入一条新数据
func (u *UserService) Create(user *model.User) error {
return db.DB.Create(user).Error
}
在router文件夹下面定义一个index.go
和 一个user_router.go
文件.
我们目前采用这种方式管理路由
router/
user_routes.go
order_routes.go
product_routes.go
index.go
其中每个模块用一个对应文件来表示. 最后在index.go 进行统一管理.
user_router.go
package router
import (
"github.com/labstack/echo/v4"
"quick-start/handle"
)
var userHandle = handle.UserHandler{}
// 定义user相关的路由
func SetupUserRoutes(e *echo.Echo) {
e.POST("/user/create", userHandle.Create)
}
index.go
package router
import (
"github.com/labstack/echo/v4"
)
// 统一管理路由
func SetupRoutes(e *echo.Echo) {
SetupUserRoutes(e)
}
打开任意一款测试软件, 我这里使用的是APIPOST
创建一个post
请求, 请求地址为http://127.0.0.1:8080/user/create
创建成功
在下面的文章中, 会介绍更多的ECHO 的api 以及Gorm 的使用方法. 喜欢的话, 欢迎点赞收藏~