整站网站优化费用,宁夏高端网站建设,网站公司怎么做推广方案,百度推广还要求做网站文章目录 安装URL和路由分组2. 带参数的url3. 获取路由分组的参数 获取参数1. 获取get参数2. 获取post参数3. get、post混合 JSON 、 ProtoBuf渲染1. 输出json和protobuf2. PureJSON 表单验证1. 表单的基本验证 中间件和next函数1. 无中间件启动2. 使用中间件3. 自定义组件 设置… 文章目录 安装URL和路由分组2. 带参数的url3. 获取路由分组的参数 获取参数1. 获取get参数2. 获取post参数3. get、post混合 JSON 、 ProtoBuf渲染1. 输出json和protobuf2. PureJSON 表单验证1. 表单的基本验证 中间件和next函数1. 无中间件启动2. 使用中间件3. 自定义组件 设置静态文件路径和HTML文件1. 设置静态文件路径2. index.html内容3. templates/posts/index.tmpl4. templates/users/index.tmpl 优雅重启或停止gorm1. 什么是orm2. 常用orm3. orm的优缺点4. 如何正确看待orm和sql之间的关系 官方手册
安装
go get -u github.com/gin-gonic/gin 代码
package mainimport github.com/gin-gonic/gin
# func main() {r : gin.Default()r.GET(/ping, func(c *gin.Context) {c.JSON(200, gin.H{message: pong,})})r.Run() // listen and serve on 0.0.0.0:8080
}使用get、post、put等http方法
func main() {// 使⽤默认中间件创建⼀个gin路由器// logger and recovery (crash-free) 中间件router : gin.Default()router.GET(/someGet, getting)router.POST(/somePost, posting)router.PUT(/somePut, putting)router.DELETE(/someDelete, deleting)router.PATCH(/somePatch, patching)router.HEAD(/someHead, head)router.OPTIONS(/someOptions, options)// 默认启动的是 8080端⼝也可以⾃⼰定义启动端⼝router.Run()// router.Run(:3000) for a hard coded port
}URL和路由分组
路由分组
func main() {router : gin.Default()// Simple group: v1v1 : router.Group(/v1){v1.POST(/login, loginEndpoint)v1.POST(/submit, submitEndpoint)v1.POST(/read, readEndpoint)}// Simple group: v2v2 : router.Group(/v2){v2.POST(/login, loginEndpoint)v2.POST(/submit, submitEndpoint)v2.POST(/read, readEndpoint)}router.Run(:8082)
}2. 带参数的url
package mainimport (github.com/gin-gonic/ginnet/http)func main() {r : gin.Default()r.GET(/ping, func(c *gin.Context) {c.JSON(200, gin.H{message: pong,})})r.GET(/user/:name/:action/, func(c *gin.Context) {name : c.Param(name)action : c.Param(action)c.String(http.StatusOK, %s is %s, name, action)})r.GET(/user/:name/*action, func(c *gin.Context) {name : c.Param(name)action : c.Param(action)c.String(http.StatusOK, %s is %s, name, action)})r.Run(:8082)
}3. 获取路由分组的参数
package mainimport github.com/gin-gonic/gintype Person struct {ID string uri:id binding:required,uuidName string uri:name binding:required}func main() {route : gin.Default()route.GET(/:name/:id, func(c *gin.Context) {var person Personif err : c.ShouldBindUri(person); err ! nil {c.JSON(400, gin.H{msg: err})return}c.JSON(200, gin.H{name: person.Name, uuid: person.ID})})route.Run(:8088)
}获取参数
1. 获取get参数
func main() {router : gin.Default()// 匹配的url格式: /welcome?firstnameJanelastnameDoerouter.GET(/welcome, func(c *gin.Context) {firstname : c.DefaultQuery(firstname, Guest)lastname : c.Query(lastname) // 是 c.Request.URL.Query().Get(lastnamec.String(http.StatusOK, Hello %s %s, firstname, lastname)})router.Run(:8080)
}2. 获取post参数
func main() {router : gin.Default()router.POST(/form_post, func(c *gin.Context) {message : c.PostForm(message)nick : c.DefaultPostForm(nick, anonymous) // 此⽅法可以设置默认值c.JSON(200, gin.H{status: posted,message: message,nick: nick,})})router.Run(:8080)
}3. get、post混合
POST /post?id1234page1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
namemanumessagethis_is_greatfunc main() {router : gin.Default()router.POST(/post, func(c *gin.Context) {id : c.Query(id)page : c.DefaultQuery(page, 0)name : c.PostForm(name)message : c.PostForm(message)fmt.Printf(id: %s; page: %s; name: %s; message: %s, id, page, name, mes})router.Run(:8080)
}JSON 、 ProtoBuf渲染
1. 输出json和protobuf
新建user.proto文件
syntax proto3;
option go_package .;proto;
message Teacher {string name 1;repeated string course 2;
}package main
import (
github.com/gin-gonic/gin
net/http
start/gin_t/proto
)
func main() {r : gin.Default()// gin.H is a shortcut for map[string]interface{}r.GET(/someJSON, func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{message: hey, status: http.StatusOK})})r.GET(/moreJSON, func(c *gin.Context) {// You also can use a structvar msg struct {Name string json:userMessage stringNumber int}msg.Name Lenamsg.Message heymsg.Number 123// Note that msg.Name becomes user in the JSON// Will output : {user: Lena, Message: hey, Number: 123}c.JSON(http.StatusOK, msg)})r.GET(/someProtoBuf, func(c *gin.Context) {courses : []string{python, django, go}// The specific definition of protobuf is written in the testdata/protoexName: bobby,Course: courses,}// Note that data becomes binary data in the response// Will output protoexample.Test protobuf serialized datac.ProtoBuf(http.StatusOK, data)})// Listen and serve on 0.0.0.0:8080r.Run(:8083)
}2. PureJSON
通常情况下JSON会将特殊的HTML字符替换为对应的unicode字符比如 替换为 \u003c 如果想原样输出html则使用PureJSON
func main() {r : gin.Default()// Serves unicode entitiesr.GET(/json, func(c *gin.Context) {c.JSON(200, gin.H{html: bHello, world!/b,})})// Serves literal charactersr.GET(/purejson, func(c *gin.Context) {c.PureJSON(200, gin.H{html: bHello, world!/b,})})// listen and serve on 0.0.0.0:8080r.Run(:8080)
}表单验证
1. 表单的基本验证
若要将请求主体绑定到结构体中请使用模型绑定目前支持JSON、XML、YAML和标准表单值(foobarboobaz)的绑定。 Gin使用 go-playground/validator 验证参数
需要在绑定的字段上设置tag比如绑定格式为json需要这样设置 json:“fieldname” 。 此外Gin还提供了两套绑定方法
Must bind Methods - Bind , BindJSON , BindXML , BindQuery , BindYAML Behavior - 这些方法底层使用 MustBindWith 如果存在绑定错误请求将被以下指令中止 c. AbortWithError(400,err).SetType(ErrorTypeBind) 响应状态代码会被设置为400请求头 Content-Type 被设置为 text/plain; charsetutf-8 。注意如果你试图在此之后设置响应代码将会发出一个警告 [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422 如果你希望更好地控制行为请使用 ShouldBind 相关的方法Should bind Methods - ShouldBind , ShouldBindJSON , ShouldBindXML , ShouldBindQuery , ShouldBindYAML Behavior - 这些方法底层使用 ShouldBindWith 如果存在绑定错误则返回错误开发人员可以正确处理请求和错误。
当我们使用绑定方法时Gin会根据Content-Type推断出使用哪种绑定器如果你确定你绑定的是什么你可以使用 MustBindWith 或者 BindingWith 。你还可以给字段指定特定规则的修饰符如果一个字段用 binding:“required” 修饰并且在绑定时该字段的值为空那么将返回一个错误。
// 绑定为json
type Login struct {User string form:user json:user xml:user binding:requiredPassword string form:password json:password xml:password binding:requ
}type SignUpParam struct {Age uint8 json:age binding:gte1,lte130Name string json:name binding:requiredEmail string json:email binding:required,emailPassword string json:password binding:requiredRePassword string json:re_password binding:required,eqfieldPassword
}
func main() {router : gin.Default()// Example for binding JSON ({user: manu, password: 123})router.POST(/loginJSON, func(c *gin.Context) {var json Loginif err : c.ShouldBindJSON(json); err ! nil {c.JSON(http.StatusBadRequest, gin.H{error: err.Error()})return}if json.User ! manu || json.Password ! 123 {c.JSON(http.StatusUnauthorized, gin.H{status: unauthorized})return}c.JSON(http.StatusOK, gin.H{status: you are logged in})})// Example for binding a HTML form (usermanupassword123)router.POST(/loginForm, func(c *gin.Context) {var form Login// This will infer what binder to use depending on the content-type headeif err : c.ShouldBind(form); err ! nil {c.JSON(http.StatusBadRequest, gin.H{error: err.Error()})return}if form.User ! manu || form.Password ! 123 {c.JSON(http.StatusUnauthorized, gin.H{status: unauthorized})return}c.JSON(http.StatusOK, gin.H{status: you are logged in})})r.POST(/signup, func(c *gin.Context) {var u SignUpParamif err : c.ShouldBind(u); err ! nil {c.JSON(http.StatusOK, gin.H{msg: err.Error(),})return}// 保存⼊库等业务逻辑代码...c.JSON(http.StatusOK, success)})// Listen and serve on 0.0.0.0:8080router.Run(:8080)
}
中间件和next函数
1. 无中间件启动
#使⽤
r : gin.New()
#替代
// 默认启动⽅式包含 Logger、Recovery 中间件
r : gin.Default()2. 使用中间件
func main() {
// 创建⼀个不包含中间件的路由器r : gin.New()// 全局中间件// 使⽤ Logger 中间件r.Use(gin.Logger())// 使⽤ Recovery 中间件r.Use(gin.Recovery())// 路由添加中间件可以添加任意多个r.GET(/benchmark, MyBenchLogger(), benchEndpoint)// 路由组中添加中间件// authorized : r.Group(/, AuthRequired())// exactly the same as:authorized : r.Group(/)// per group middleware! in this case we use the custom created// AuthRequired() middleware just in the authorized group.authorized.Use(AuthRequired()){authorized.POST(/login, loginEndpoint)authorized.POST(/submit, submitEndpoint)authorized.POST(/read, readEndpoint)// nested grouptesting : authorized.Group(testing)testing.GET(/analytics, analyticsEndpoint)}// Listen and serve on 0.0.0.0:8080r.Run(:8080)
}3. 自定义组件
func Logger() gin.HandlerFunc {return func(c *gin.Context) {t : time.Now()// Set example variablec.Set(example, 12345)// before requestc.Next()// after requestlatency : time.Since(t)log.Print(latency)// access the status we are sendingstatus : c.Writer.Status()log.Println(status)}}func main() {r : gin.New()r.Use(Logger())r.GET(/test, func(c *gin.Context) {example : c.MustGet(example).(string)// it would print: 12345log.Println(example)})// Listen and serve on 0.0.0.0:8080r.Run(:8080)
}设置静态文件路径和HTML文件
1. 设置静态文件路径
package main
import (
net/http
github.com/gin-gonic/gin
)
func main() {// 创建⼀个默认的路由引擎r : gin.Default()// 配置模板r.LoadHTMLGlob(templates/**/*)//router.LoadHTMLFiles(templates/template1.html, templates/template2.html// 配置静态⽂件夹路径 第⼀个参数是api第⼆个是⽂件夹路径r.StaticFS(/static, http.Dir(./static))// GET请求⽅式/hello请求的路径// 当客户端以GET⽅法请求/hello路径时会执⾏后⾯的匿名函数r.GET(/posts/index, func(c *gin.Context) {// c.JSON返回JSON格式的数据c.HTML(http.StatusOK, posts/index.tmpl, gin.H{title: posts/index,})})r.GET(gets/login, func(c *gin.Context) {c.HTML(http.StatusOK, posts/login.tmpl, gin.H{title: gets/login,})})// 启动HTTP服务默认在0.0.0.0:8080启动服务r.Run()
}2. index.html内容
htmlh1{{ .title }}/h1
/html3. templates/posts/index.tmpl
{{ define posts/index.tmpl }}htmlh1{{ .title }}/h1pUsing posts/index.tmpl/p/html
{{ end }}4. templates/users/index.tmpl
{{ define users/index.tmpl }}
htmlh1{{ .title }}
/h1pUsing users/index.tmpl/p
/html
{{ end }}优雅重启或停止
package main
import (contextlognet/httposos/signalsyscalltimegithub.com/gin-gonic/gin
)
func main() {router : gin.Default()router.GET(/, func(c *gin.Context) {time.Sleep(5 * time.Second)c.String(http.StatusOK, Welcome Gin Server)})
srv : http.Server{Addr: :8080,Handler: router,
}
go func() {// service connectionsif err : srv.ListenAndServe(); err ! nil err ! http.ErrServerClosedlog.Fatalf(listen: %s\n, err)}
}()// Wait for interrupt signal to gracefully shutdown the server with// a timeout of 5 seconds.quit : make(chan os.Signal)// kill (no param) default send syscanll.SIGTERM// kill -2 is syscall.SIGINT// kill -9 is syscall. SIGKILL but cant be catch, so dont need add itsignal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)-quitlog.Println(Shutdown Server ...)ctx, cancel : context.WithTimeout(context.Background(), 5*time.Second)defer cancel()if err : srv.Shutdown(ctx); err ! nil {log.Fatal(Server Shutdown:, err)
select {case -ctx.Done():log.Println(timeout of 5 seconds.)}log.Println(Server exiting)
}gorm
1. 什么是orm
ORM全称是Object Relational Mapping(对象关系映射)其主要作用是在编程中把面向对象的概念跟数据库中表的概念对应起来。举例来说就是我定义一个对象那就对应着一张表这个对象的实例就对应着表中的一条记录。
对于数据来说最重要最常用的是表表中有列 orm就是将一张表映射成一个类表中的列映射成类中的一个类。java 、python但是针对go语言而言struct就是列如何映射是因为列可以映射成struct中的类型int-int,但是有另一个问题 就是数据库中的列具备很好的描述性但是struct有tag。执行sql 需要我们有足够的sql语句基础、需要我们懂得不同的数据的sql
2. 常用orm
个人而言不用太去纠结应该选择哪一个orm框架但是实际上你用熟悉了一个其他的orm迁移成本很低我们选个一个star数量最高的一定不会有错这些差异也不会很大 sql语言远比orm重要的多 https://github.com/go-gorm/gorm https://github.com/facebook/ent https://github.com/jmoiron/sqlx https://gitea.com/xorm/xorm/src/branch/master/README_CN.md https://github.com/didi/gendry/blob/master/translation/zhcn/README.md
3. orm的优缺点
优点
提高了开发效率。屏蔽sql细节。可以自动对实体Entity对象与数据库中的Table进行字段与属性的映射不用直接SQL编码屏蔽各种数据库之间的差异 缺点orm会牺牲程序的执行效率和会固定思维模式太过依赖orm会导致sql理解不够对于固定的orm依赖过重导致切换到其他的orm代价高
4. 如何正确看待orm和sql之间的关系
sql为主orm为辅orm主要目的是为了增加代码可维护性和开发效率
一定要学好
group by子查询having子句 文章转载自: http://www.morning.zxybw.cn.gov.cn.zxybw.cn http://www.morning.dwyyf.cn.gov.cn.dwyyf.cn http://www.morning.frxsl.cn.gov.cn.frxsl.cn http://www.morning.brqjs.cn.gov.cn.brqjs.cn http://www.morning.ltspm.cn.gov.cn.ltspm.cn http://www.morning.ydflc.cn.gov.cn.ydflc.cn http://www.morning.hdpcn.cn.gov.cn.hdpcn.cn http://www.morning.bgnkl.cn.gov.cn.bgnkl.cn http://www.morning.rwmq.cn.gov.cn.rwmq.cn http://www.morning.bxyzr.cn.gov.cn.bxyzr.cn http://www.morning.psxcr.cn.gov.cn.psxcr.cn http://www.morning.qclmz.cn.gov.cn.qclmz.cn http://www.morning.qljxm.cn.gov.cn.qljxm.cn http://www.morning.flchj.cn.gov.cn.flchj.cn http://www.morning.myrmm.cn.gov.cn.myrmm.cn http://www.morning.hxmqb.cn.gov.cn.hxmqb.cn http://www.morning.rjrnx.cn.gov.cn.rjrnx.cn http://www.morning.lftpl.cn.gov.cn.lftpl.cn http://www.morning.ssqrd.cn.gov.cn.ssqrd.cn http://www.morning.zpyh.cn.gov.cn.zpyh.cn http://www.morning.jlboyuan.cn.gov.cn.jlboyuan.cn http://www.morning.brwei.com.gov.cn.brwei.com http://www.morning.kzqpn.cn.gov.cn.kzqpn.cn http://www.morning.yrjkz.cn.gov.cn.yrjkz.cn http://www.morning.fnmgr.cn.gov.cn.fnmgr.cn http://www.morning.hhxpl.cn.gov.cn.hhxpl.cn http://www.morning.dhxnr.cn.gov.cn.dhxnr.cn http://www.morning.wfjyn.cn.gov.cn.wfjyn.cn http://www.morning.cwcdr.cn.gov.cn.cwcdr.cn http://www.morning.jxlnr.cn.gov.cn.jxlnr.cn http://www.morning.cywf.cn.gov.cn.cywf.cn http://www.morning.pgjyc.cn.gov.cn.pgjyc.cn http://www.morning.nshhf.cn.gov.cn.nshhf.cn http://www.morning.ruyuaixuexi.com.gov.cn.ruyuaixuexi.com http://www.morning.xzrbd.cn.gov.cn.xzrbd.cn http://www.morning.mjats.com.gov.cn.mjats.com http://www.morning.nynlf.cn.gov.cn.nynlf.cn http://www.morning.xrpwk.cn.gov.cn.xrpwk.cn http://www.morning.xhhzn.cn.gov.cn.xhhzn.cn http://www.morning.qrwdg.cn.gov.cn.qrwdg.cn http://www.morning.drndl.cn.gov.cn.drndl.cn http://www.morning.dnbhd.cn.gov.cn.dnbhd.cn http://www.morning.lwrcg.cn.gov.cn.lwrcg.cn http://www.morning.bfgpn.cn.gov.cn.bfgpn.cn http://www.morning.mdgpp.cn.gov.cn.mdgpp.cn http://www.morning.sfzwm.cn.gov.cn.sfzwm.cn http://www.morning.jftl.cn.gov.cn.jftl.cn http://www.morning.kpcjl.cn.gov.cn.kpcjl.cn http://www.morning.rkfh.cn.gov.cn.rkfh.cn http://www.morning.jftl.cn.gov.cn.jftl.cn http://www.morning.yhplt.cn.gov.cn.yhplt.cn http://www.morning.yxzfl.cn.gov.cn.yxzfl.cn http://www.morning.ykmtz.cn.gov.cn.ykmtz.cn http://www.morning.rpwht.cn.gov.cn.rpwht.cn http://www.morning.rlbg.cn.gov.cn.rlbg.cn http://www.morning.yxnkr.cn.gov.cn.yxnkr.cn http://www.morning.pzdxg.cn.gov.cn.pzdxg.cn http://www.morning.spbp.cn.gov.cn.spbp.cn http://www.morning.ycgrl.cn.gov.cn.ycgrl.cn http://www.morning.bydpr.cn.gov.cn.bydpr.cn http://www.morning.ljbm.cn.gov.cn.ljbm.cn http://www.morning.brhxd.cn.gov.cn.brhxd.cn http://www.morning.yrhpg.cn.gov.cn.yrhpg.cn http://www.morning.mumgou.com.gov.cn.mumgou.com http://www.morning.xbtlt.cn.gov.cn.xbtlt.cn http://www.morning.grqlc.cn.gov.cn.grqlc.cn http://www.morning.pgggs.cn.gov.cn.pgggs.cn http://www.morning.sryyt.cn.gov.cn.sryyt.cn http://www.morning.rnqnp.cn.gov.cn.rnqnp.cn http://www.morning.dlgjdg.cn.gov.cn.dlgjdg.cn http://www.morning.cfhwn.cn.gov.cn.cfhwn.cn http://www.morning.zhmgcreativeeducation.cn.gov.cn.zhmgcreativeeducation.cn http://www.morning.ygflz.cn.gov.cn.ygflz.cn http://www.morning.dktyc.cn.gov.cn.dktyc.cn http://www.morning.fkcjs.cn.gov.cn.fkcjs.cn http://www.morning.lnbcg.cn.gov.cn.lnbcg.cn http://www.morning.nkqnn.cn.gov.cn.nkqnn.cn http://www.morning.fwcnx.cn.gov.cn.fwcnx.cn http://www.morning.wfbs.cn.gov.cn.wfbs.cn http://www.morning.srjbs.cn.gov.cn.srjbs.cn