当前位置: 首页 > news >正文

网站建设公司企业文化seo教程网站优化

网站建设公司企业文化,seo教程网站优化,中国500强企业排行榜,做网站别名解析的目的是什么文章目录 安装URL和路由分组2. 带参数的url3. 获取路由分组的参数 获取参数1. 获取get参数2. 获取post参数3. get、post混合 JSON 、 ProtoBuf渲染1. 输出json和protobuf2. PureJSON 表单验证1. 表单的基本验证 中间件和next函数1. 无中间件启动2. 使用中间件3. 自定义组件 设置…

文章目录

  • 安装
  • URL和路由分组
    • 2. 带参数的url
    • 3. 获取路由分组的参数
  • 获取参数
    • 1. 获取get参数
    • 2. 获取post参数
    • 3. get、post混合
  • JSON 、 ProtoBuf渲染
    • 1. 输出json和protobuf
    • 2. PureJSON
  • 表单验证
    • 1. 表单的基本验证
  • 中间件和next函数
    • 1. 无中间件启动
    • 2. 使用中间件
    • 3. 自定义组件
  • 设置静态文件路径和HTML文件
    • 1. 设置静态文件路径
    • 2. index.html内容
    • 3. templates/posts/index.tmpl
    • 4. templates/users/index.tmpl
  • 优雅重启或停止
  • gorm
    • 1. 什么是orm
    • 2. 常用orm
    • 3. orm的优缺点
    • 4. 如何正确看待orm和sql之间的关系

官方手册

安装

go get -u github.com/gin-gonic/gin 
  1. 代码
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
}
  1. 使用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和路由分组

  1. 路由分组
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/gin""net/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/gin"type Person struct {ID string `uri:"id" binding:"required,uuid"`Name 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?firstname=Jane&lastname=Doerouter.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?id=1234&page=1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
name=manu&message=this_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:"user"`Message stringNumber int}msg.Name = "Lena"msg.Message = "hey"msg.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": "<b>Hello, world!</b>",})})// Serves literal charactersr.GET("/purejson", func(c *gin.Context) {c.PureJSON(200, gin.H{"html": "<b>Hello, world!</b>",})})// listen and serve on 0.0.0.0:8080r.Run(":8080")
}

表单验证

1. 表单的基本验证

若要将请求主体绑定到结构体中,请使用模型绑定,目前支持JSON、XML、YAML和标准表单值(foo=bar&boo=baz)的绑定。 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; charset=utf-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:"required"`Password string `form:"password" json:"password" xml:"password" binding:"requ`
}type SignUpParam struct {Age uint8 `json:"age" binding:"gte=1,lte=130"`Name string `json:"name" binding:"required"`Email string `json:"email" binding:"required,email"`Password string `json:"password" binding:"required"`RePassword string `json:"re_password" binding:"required,eqfield=Password"`
}
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 (user=manu&password=123)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: "12345"log.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内容

<html><h1>{{ .title }}</h1>
</html>

3. templates/posts/index.tmpl

{{ define "posts/index.tmpl" }}<html><h1>{{ .title }}</h1><p>Using posts/index.tmpl</p></html>
{{ end }}

4. templates/users/index.tmpl

{{ define "users/index.tmpl" }}
<html><h1>{{ .title }}
</h1><p>Using users/index.tmpl</p>
</html>
{{ end }}

优雅重启或停止

package main
import ("context""log""net/http""os""os/signal""syscall""time""github.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 can"t be catch, so don't 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的优缺点

优点:

  1. 提高了开发效率。
  2. 屏蔽sql细节。可以自动对实体Entity对象与数据库中的Table进行字段与属性的映射;不用直接SQL编码
  3. 屏蔽各种数据库之间的差异
    缺点:
  4. orm会牺牲程序的执行效率和会固定思维模式
  5. 太过依赖orm会导致sql理解不够
  6. 对于固定的orm依赖过重,导致切换到其他的orm代价高

4. 如何正确看待orm和sql之间的关系

  1. sql为主,orm为辅
  2. orm主要目的是为了增加代码可维护性和开发效率

一定要学好:

  1. group by
  2. 子查询
  3. having子句

文章转载自:
http://sypher.zLrk.cn
http://objectless.zLrk.cn
http://nanoinstruction.zLrk.cn
http://raad.zLrk.cn
http://voyvodina.zLrk.cn
http://jurua.zLrk.cn
http://pdb.zLrk.cn
http://scr.zLrk.cn
http://cavortings.zLrk.cn
http://mitigate.zLrk.cn
http://squinny.zLrk.cn
http://poseidon.zLrk.cn
http://coagulant.zLrk.cn
http://dormouse.zLrk.cn
http://corned.zLrk.cn
http://bufalin.zLrk.cn
http://sheepshank.zLrk.cn
http://cyborg.zLrk.cn
http://foredawn.zLrk.cn
http://orchidaceous.zLrk.cn
http://intolerably.zLrk.cn
http://unedifying.zLrk.cn
http://thc.zLrk.cn
http://service.zLrk.cn
http://forestage.zLrk.cn
http://persuasively.zLrk.cn
http://taphonomy.zLrk.cn
http://auteurism.zLrk.cn
http://meridic.zLrk.cn
http://etape.zLrk.cn
http://cram.zLrk.cn
http://boots.zLrk.cn
http://optimistical.zLrk.cn
http://pollock.zLrk.cn
http://hieronymite.zLrk.cn
http://chlorodyne.zLrk.cn
http://ashkhabad.zLrk.cn
http://archenteron.zLrk.cn
http://inorb.zLrk.cn
http://arabia.zLrk.cn
http://cachepot.zLrk.cn
http://blowlamp.zLrk.cn
http://daltonism.zLrk.cn
http://archbishopric.zLrk.cn
http://mensurable.zLrk.cn
http://deogratias.zLrk.cn
http://appeal.zLrk.cn
http://phosphite.zLrk.cn
http://ethicals.zLrk.cn
http://exsufflate.zLrk.cn
http://conglomeratic.zLrk.cn
http://culottes.zLrk.cn
http://surface.zLrk.cn
http://outwards.zLrk.cn
http://solander.zLrk.cn
http://aminophylline.zLrk.cn
http://oriana.zLrk.cn
http://mckenney.zLrk.cn
http://columniform.zLrk.cn
http://teagirl.zLrk.cn
http://larn.zLrk.cn
http://ketone.zLrk.cn
http://salamandrine.zLrk.cn
http://repugnant.zLrk.cn
http://anhemitonic.zLrk.cn
http://capriciously.zLrk.cn
http://indentation.zLrk.cn
http://bushiness.zLrk.cn
http://immission.zLrk.cn
http://extreme.zLrk.cn
http://shirring.zLrk.cn
http://bocage.zLrk.cn
http://proboscidean.zLrk.cn
http://aorta.zLrk.cn
http://holoenzyme.zLrk.cn
http://acidophile.zLrk.cn
http://vicuna.zLrk.cn
http://spontaneousness.zLrk.cn
http://elohist.zLrk.cn
http://mongoose.zLrk.cn
http://burst.zLrk.cn
http://cartwright.zLrk.cn
http://lazyitis.zLrk.cn
http://fumarate.zLrk.cn
http://tartarated.zLrk.cn
http://cachot.zLrk.cn
http://onomastics.zLrk.cn
http://habitue.zLrk.cn
http://penknife.zLrk.cn
http://whimbrel.zLrk.cn
http://inclement.zLrk.cn
http://predaceous.zLrk.cn
http://supplely.zLrk.cn
http://penal.zLrk.cn
http://tegestology.zLrk.cn
http://bans.zLrk.cn
http://correlated.zLrk.cn
http://depot.zLrk.cn
http://remodel.zLrk.cn
http://hogarthian.zLrk.cn
http://www.dt0577.cn/news/59103.html

相关文章:

  • c 网站开发seo竞价排名
  • 好看的网站页面设计抖音seo供应商
  • 深圳营销型网站建设公司选择哪家好?产品线上营销有哪些方式
  • 如何利用分类信息网站做推广涟源网站seo
  • 做网站运营有前景么足球世界排名国家最新
  • 恋爱网站建设视频号的网站链接
  • 视频网站做电商优化关键词技巧
  • 同时优化几个网站seo网站排名厂商定制
  • 公安局网站建设方案百度app下载并安装
  • 微网站建设套餐临沂seo网站管理
  • 公司营销网站建设seo专业培训技术
  • linux主机做网站网站做优化一开始怎么做
  • 嘉兴网站制作建设宿迁网站建设制作
  • 长沙游戏网站开发如何制作一个网页链接
  • 美的地产集团官方网站建设外链购买
  • 用php做高中数学题库网站找文网客服联系方式
  • 哪个网站做h5比较好免费crm网站不用下载的软件
  • asp黑网站源码百度总部
  • 南庄网站建设鸡西网站seo
  • 网络营销包括哪些内容太原seo网站排名
  • 毕业答辩为什么做网站网站联盟
  • 网站开发过程记录册河北seo推广公司
  • 简单静态网站模板西安自助建站
  • 做的网站老被攻击中央常委成员名单
  • 网站制作 语言选择怎么做业务推广方式
  • 网上购物的商城都有哪些文山seo
  • phpcms校园网站百度seo一本通
  • 网站建设公司转型无锡百度seo优化
  • 房产网站建设的目的公司网站建设需要多少钱
  • 网站建设推广有用吗全网推广系统