gin框架之初步

因为公司业务的需要,开始熟悉go的重要框架之一的Gin框架,之前用beego写了二三十个接口,初步感觉gin没beego那么重那么繁杂,更简洁。需要go get 一下gin框架
package main
import(
“github.com/gin-gonic/gin” //go get “github.com/gin-gonic/gin”
“log”
“net/http”
)
func main(){
r := gin.Default()
r.GET("/api/test", func(c *gin.Context) {
c.JSON(200, gin.H{“msg”:“chenhaibo Gin ok”})
})
r.GET("/JSONP", func(c *gin.Context) {
data := map[string]interface{}{
“foo”:“chenhaibo”,
}
log.Println(“this is a log”)
c.JSONP(http.StatusOK, data)
})
r.Run(":3030")
}
http://localhost:3030/api/test
{“msg”:“chenhaibo Gin ok”}
http://localhost:3030/JSONP
{“foo”:“chenhaibo”}
使用Gin操作数据库 添加和查询记录
CREATE TABLE person (
id int(11) NOT NULL AUTO_INCREMENT,
first_name varchar(40) NOT NULL DEFAULT ‘’,
last_name varchar(40) NOT NULL DEFAULT ‘’,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
创建数据表之后,初始化数据库连接池:需要go get “github.com/go-sql-driver/mysql” mysql驱动
func main() {
db, err := sql.Open(“mysql”, “root:@tcp(127.0.0.1:3306)/test?parseTime=true”)
if err != nil{
log.Fatalln(err)
}
defer db.Close()
db.SetMaxIdleConns(20)
db.SetMaxOpenConns(20)
if err := db.Ping(); err != nil{
log.Fatalln(err)
}
router := gin.Default()
router.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, “It works”)
})
router.Run(":3030")
} //http://localhost:3030/ 测试数据库连接 OK
使用sql.Open方法会创建一个数据库连接池db。这个db不是数据库连接,它是一个连接池,只有当真正数据库通信的时候才创建连接。例如这里的db.Ping的操作。db.SetMaxIdleConns(20)和db.SetMaxOpenConns(20)分别设置数据库的空闲连接和最大打开连接,即向Mysql服务端发出的所有连接的最大数目。
如果不设置,默认都是0,表示打开的连接没有限制。我在压测的时候,发现会存在大量的TIME_WAIT状态的连接,虽然mysql的连接数没有上升。设置了这两个参数之后,不在存在大量TIME_WAIT状态的连接了。而且qps也没有明显的变化,出于对数据库的保护,最好设置这连个参数
CURD 增删改查------------------------------
添加一条记录POST------------------在main方法里下面
package main
import (
“database/sql”
“fmt”
“github.com/gin-gonic/gin”
_ “github.com/go-sql-driver/mysql”
“log”
“net/http”
)

func main() {
db, err := sql.Open(“mysql”, “root:root@tcp(127.0.0.1:3306)/sys?parseTime=true”)
if err != nil{
log.Fatalln(err)
}
defer db.Close()
db.SetMaxIdleConns(20)
db.SetMaxOpenConns(20)
if err := db.Ping(); err != nil{
log.Fatalln(err)
}
router := gin.Default()
router.GET("/", func(c *gin.Context) { //测试数据库连接
c.String(http.StatusOK, “It works”)
})
router.POST("/addPerson", func(c *gin.Context) {
firstName := c.Request.FormValue(“first_name”)
lastName := c.Request.FormValue(“last_name”)
rs, err := db.Exec(“INSERT INTO person(first_name, last_name) VALUES (?, ?)”, firstName, lastName)
if err != nil {
log.Fatalln(err)
}
id, err := rs.LastInsertId()
if err != nil {
log.Fatalln(err)
}
fmt.Println(“insert person Id {}”, id)
msg := fmt.Sprintf(“insert successful %d”, id)
c.JSON(http.StatusOK, gin.H{
“msg”: msg,
})
})
router.Run(":3030")
} //postman里POST新增一条记录
在这里插入图片描述
查询列表 Query----------------
在main函数的上方定义Person结构:
router.GET("/list", func(c *gin.Context) { //本段写在 main方法里
rows, err := db.Query(“SELECT id, first_name, last_name FROM person”)
if err != nil {
log.Fatalln(err)
}
defer rows.Close()
persons := make([]Person, 0)
for rows.Next(){
var person Person
rows.Scan(&person.Id, &person.FirstName, &person.LastName)
persons = append(persons, person)
}
if err = rows.Err(); err != nil{
log.Fatalln(err)
}
c.JSON(http.StatusOK, gin.H{
“persons”:persons,
})
}) //http://localhost:3030/list
{“persons”:[{“id”:1,“first_name”:“chen”,“last_name”:“haibo”},{“id”:2,“first_name”:“陈”,“last_n…
创建一个[]Person的切片。
使用make,而不是直接使用var persons []Person的声明方式。还是有所差别的,使用make的方式,当数组切片没有元素的时候,Json会返回[]。如果直接声明,json会返回null。
接下来就是使用rows对象的Next方法,遍历所查询的数据,一个个绑定到person对象上,最后append到persons切片。
查询单条记录 QueryRow-----------------
查询列表需要使用迭代rows对象,查询单个记录,就没这么麻烦了。虽然也可以迭代一条记录的结果集。因为查询单个记录的操作实在太常用了,因此golang的database/sql也专门提供了查询方法
router.GET(”/person/:id", func(c *gin.Context) { //
id := c.Param(“id”)
var person Person
err := db.QueryRow(“SELECT id, first_name, last_name FROM person WHERE id=?”, id).Scan(
&person.Id, &person.FirstName, &person.LastName,
)
if err != nil {
log.Println(err)
c.JSON(http.StatusOK, gin.H{
“person”: nil,
})
return
}
c.JSON(http.StatusOK, gin.H{
“person”: person,
})
}) // http://localhost:3030/person/:id
{“person”:null}
http://localhost:3030/person/1
{“person”:{“id”:1,“first_name”:“chen”,“last_name”:“haibo”}}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值