[Golang] Gin框架学习笔记
0x0 Gin简介
1.Gin 是什么?
Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。如果你需要极好的性能,使用 Gin 吧。
2.Gin相关地址
doc:https://gin-gonic.com/zh-cn/docs/
github:https://github.com/gin-gonic/gin
0x1 快速开始
1. 用module模式创建工程
mkdir web_api
cd web_api
go mod init web_api
2.创建main.go
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
3. 运行
go run main.go
4. 浏览器打开 127.0.0.1:8080/ping
0x2 实践
1. 说明
1)这是一个简单的例子,实现了通过id查找数据库获取用户名字的功能。
2)使用了MVC结构,当然也可以不套用这种结构。好处就是开发web程序结构会清晰很多。
3)使用了go modules的包管理方式确实方便很多。不清楚的可以看我另外一篇关于go modules的介绍https://www.cnblogs.com/mrblue/p/11277100.html
4)依赖了yml和gorm库
2.目录结构如下
│ config.yml
│ go.mod
│ go.sum
│ main.go
│ Makefile
│ README.md
├─app
│ app.go
│ handle.go
│ routers.go
│
├─controllers
│ user.go
│
├─models
│ model.go
│ user.go
│
├─routers
│ router.go
│
└─service
user.go
3.主要文件说明
1)app/app.go 应用程序文件,负责初始化gin上下文,处理信号量
package app import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"
"web_api/routers"
"github.com/gin-gonic/gin"
) type Config struct {
Port string
Debug bool
} func Run(cfg Config) {
router := gin.Default()
routes.RegisterRouters(router)
srv := &http.Server{
Addr: ":" + cfg.Port,
Handler: router,
} go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}() quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)
<-quit
log.Println("Shutdown Server ...") ctx, cancel := context.WithTimeout(context.Background(), *time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
}
2) controllers/user.go 控制文件,获取请求参数,调用service的逻辑方法,然后返回结果
package controllers import (
"net/http" "web_api/service" "github.com/gin-gonic/gin"
) func GetName(c *gin.Context) { id := c.Param("id")
r := service.User{ID: id}
name, err := r.GetName()
if nil != err {
c.String(http.StatusInternalServerError, err.Error())
return
} c.JSON(http.StatusOK, gin.H{"error": "ok", "name": name})
}
3) models/model.go 数据库的初始化
package models import (
"fmt" "github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
) // Config 配置
type Config struct {
User string
Password string
Host string
Name string
} var (
db *gorm.DB
) // Setup initializes the database instance
func Setup(cfg Config) error { var err error
db, err = gorm.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
cfg.User,
cfg.Password,
cfg.Host,
cfg.Name)) if err != nil {
return err
} db.SingularTable(true)
db.DB().SetMaxIdleConns()
db.DB().SetMaxOpenConns()
return nil
} // CloseDB closes database connection (unnecessary)
func CloseDB() {
defer db.Close()
}
4) models/user.go user数据库表的增删改查
package models import (
"github.com/jinzhu/gorm"
) type User struct {
ID string `gorm:"primary_key;type:INT(20)"`
Age int32 `gorm:"type:INT(20)"`
Name string `gorm:"type:VARCHAR(256)"`
Desc string `gorm:"type:VARCHAR(256)"`
}
func (User) TableName() string {
return "user"
}
func GetUser(id string) (*User, error) {
u := &User{
ID: id,
}
err := db.First(u).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
return u, nil
}
5) routers/router.go 定义路由
package routers import (
"web_api/controllers" "github.com/gin-gonic/gin"
) // RegisterRouters ...
func RegisterRouters(g *gin.Engine) {
g.GET("/name/:id", controllers.GetName)
}
6) service/user.go user的逻辑
package service import (
"web_api/models"
) type User struct {
ID string
} func (r *User) GetName() (string, error) {
u, err := models.GetUser(r.ID)
if nil != err {
return "", err
}
return u.Name, nil
}
7) main.go
package main import (
"flag"
"io/ioutil"
"log" "web_api/app"
"web_api/models" "gopkg.in/yaml.v2"
) // Config 配置
type Config struct {
App app.Config
Model models.Config
} var (
cfgPath = flag.String("config", "config.yml", "config file path")
) func main() {
cfg := Config{}
if data, err := ioutil.ReadFile(*cfgPath); nil != err {
panic(err)
} else {
if err := yaml.Unmarshal(data, &cfg); nil != err {
panic(err)
}
} if err := models.Setup(cfg.Model); nil != err {
panic(err)
} app.Run(cfg.App) log.Println("Server exiting")
}
4.配置文件 confg.yml
app:
port:
debug: true model:
user: root
password: xxxxx
host: 127.0.0.1:
name: mydb
5.测试
1)需要你的mysql有个叫mydb的库,里有一张叫user的表
2)查找id魏1000的人的名字,浏览器打开 http://127.0.0.1:8080/name/1000
[Golang] Gin框架学习笔记的更多相关文章
- 前端程序员学习 Golang gin 框架实战笔记之一开始玩 gin
原文链接 我是一名五六年经验的前端程序员,现在准备学习一下 Golang 的后端框架 gin. 以下是我的学习实战经验,记录下来,供大家参考. https://github.com/gin-gonic ...
- Golang gin框架学习
今天开始学习gin框架,在Github上找的示例的go-gin-example, 进度 日期 进展 疑惑 进展 1.30 下拉代码,初步了解gin的介绍.搭建 .mod文件 module原理.使用方法 ...
- kratos微服务框架学习笔记一(kratos-demo)
目录 kratos微服务框架学习笔记一(kratos-demo) kratos本体 demo kratos微服务框架学习笔记一(kratos-demo) 今年大部分时间飘过去了,没怎么更博和githu ...
- golang(gin框架),基于RESTFUL的跨语言远程通信尝试
golang(gin框架),基于RESTFUL的跨语言远程通信尝试 背景: 在今年的项目实训过程中,遇到了这样的问题: 企业老师讲课实用的技术栈是Java springboot. 实训实际给我们讲课以 ...
- phalcon(费尔康)框架学习笔记
phalcon(费尔康)框架学习笔记 http://www.qixing318.com/article/phalcon-framework-to-study-notes.html 目录结构 pha ...
- Yii框架学习笔记(二)将html前端模板整合到框架中
选择Yii 2.0版本框架的7个理由 http://blog.chedushi.com/archives/8988 刚接触Yii谈一下对Yii框架的看法和感受 http://bbs.csdn.net/ ...
- JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue
前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...
- JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序
前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...
- JavaSE中Map框架学习笔记
前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...
随机推荐
- Pandas快速上手(一):基本操作
本文包含一些 Pandas 的基本操作,旨在快速上手 Pandas 的基本操作. 读者最好有 NumPy 的基础,如果你还不熟悉 NumPy,建议您阅读NumPy基本操作快速熟悉. Pandas 数据 ...
- dfs --path sum 问题 本质上就是组合问题(有去重)
135. 数字组合 中文 English 给定一个候选数字的集合 candidates 和一个目标值 target. 找到 candidates 中所有的和为 target 的组合. 在同一个组合中, ...
- 关于background-image设置背景图片
每天进步一小步,一年进步一大步. 本篇主要介绍背景图片设置,平铺,x y方向上的平铺,是否重复显示no repeat 显示的初始位置 background-image:url(images/inde ...
- 如何使用h5py读入数据
在网上找到的方法,如下: import h5py import numpy as np #HDF5的写入: imgData = np.zeros((2,4)) f = h5py.File('HDF5_ ...
- react native redux 草稿
Provider > Provider > 使组件层级中的 方法都能够获得 Redux store.正常情况下,你的根组件应该嵌套在 Provider 中才能使用 方法. 如果你真的不想把 ...
- POJ1321-棋盘问题-(dfs)
http://poj.org/problem?id=1321 解题: dfs中,两种情况,某一行摆不摆?某一列摆不摆? #include<stdio.h> #include<iost ...
- 学习:STL_deque容器
deque容器: 功能:双端数组,可以对头端进行插入删除操作 deque与vector区别: 1.vector对于头部的插入删除效率低,数据量越大,效率越低 2.deque相对而言,对头部的插入删除速 ...
- Linglong combination
Graphic calculator usually refers to a kind of hand-held calculator that can draw function images, s ...
- 4GB以上超大文件上传和断点续传服务器的实现
随着视频网站和大数据应用的普及,特别是高清视频和4K视频应用的到来,超大文件上传已经成为了日常的基础应用需求. 但是在很多情况下,平台运营方并没有大文件上传和断点续传的开发经验,往往在网上找一些简单的 ...
- 利用伪寄存器对MSVC++进行调试的介绍
简介 让我们从我写这篇文章的原因开始.一天,一个同事让我帮他调试他遇到的问题.所以我看着他在输入代码,这时我注意到下面一行: int test = GetLastError(); 他这样做是因为他想知 ...