Gin搭建开发API

因为实际开发需要最近在学学Gin框架,感觉Gin框架比之前用的beego框架更简洁,不臃肿;准备把项目的API从laravel转到Gin;
本次完成的功能:项目搭建,主入口main.go,四个列表接口(列表,总数,分页等),两种不同的接收参数等;
端口是5050;
执行入口主文件 go run main.go

先上项目的结构图:
在这里插入图片描述
主入口文件----------------------------------
package main
import (
db “fkHalo/databases”
. “fkHalo/router”
)
func main(){
//延迟释放,当整个程序完成之后关闭数据库连接,释放资源
defer db.SqlDB.Close()
router := InitRouter()
router.Run(":5050")
}

路由文件--------------------
package router

import (
“fkHalo/api/controller”
“github.com/gin-gonic/gin”
.“fkHalo/api”
)

func InitRouter() *gin.Engine {
router := gin.Default()
router.GET("/", Index)
//获取所有门店列表(list len(list)得到总数)
router.GET("/get_all_stores", GetAllStores)
//获取所有门店列表
router.GET("/get_stores", GetStoresLists)
//获取所有门店列表 带分页 参数格式 “/:page/:pageSize/:seachKey”
router.GET("/get_stores_page/:page/:pageSize/:seachKey", GetStoresListsByPage)
//获取所有门店列表 带分页 参数格式 “?page=1&pageSize=10&seachKey=测试”
router.GET("/store/get_stores_list_page", controller.StoreGetAllStores)
return router
}
model层的store.go 我以store表为model------------------------
package models

import (
db “fkHalo/databases”
_ “github.com/gin-gonic/gin”
)
//定义门店类型结构
type Store struct {
Id int json:"id"
Name string json:"name"
CompanyId string json:"company_id"
Code string json:"code"
OpenStatus int json:"open_status"
HoursDesc string json:"hours_desc"
}

//执行非query操作,使用db的Exec方法,在MySQL中使用?做占位符
//GetPersons 读取MySQL的数据需要有一个绑定的过程,db.Query()方法返回一个rows对象,这个数据库连接随即转移到这个对象,因此我们需要定义rows.Close()操作,然后创建一个[]Person的切片
//使用make,而不是直接使用var persons []Person的声明方式。还是有所差别的,使用make的方式,当数组切片没有元素的时候,Json会返回[]。如果直接声明,json会返回null。
//接下来就是使用rows对象的Next()方法,遍历所查询的数据,一个个绑定到person对象上,最后append到person切片。
func (s *Store) GetStores() (stores []Store, err error){
stores = make([]Store, 0)
rows, err := db.SqlDB.Query(“select id,name,company_id,code,open_status,hours_desc from store”)
defer rows.Close() //用于注册延迟调用 调用直到 return 前才被执。因此,可以用来做资源清理
if err != nil{
return
}
for rows.Next(){
var store Store
rows.Scan(&store.Id, &store.Code, &store.Name,&store.CompanyId,&store.OpenStatus,&store.HoursDesc)
stores = append(stores,store)
}
if err = rows.Err(); err != nil{
return
}
return
}
//获取门店数量
func (s *Store) GetStoreTotal() (storeIds []Store, err error){
storeIds = make([]Store, 0)
rows, err := db.SqlDB.Query(“select id from store where is_deleted = 0”)
defer rows.Close()
if err != nil{
return
}
for rows.Next(){
var store Store
rows.Scan(&store.Id)
storeIds = append(storeIds,store)
}
if err = rows.Err(); err != nil{
return
}
return
}

//获取所有门店列表 带分页
func GetStoresByPage(page int, pageSize int, seachKey string) (stores []Store, err error) {
stores = make([]Store, 0)
if seachKey != “”{
rows, err_page := db.SqlDB.Query(“select id,name,company_id,code,open_status,hours_desc from store where name like '%”+seachKey+"%’ limit ?,?",(page-1)*pageSize, pageSize)
if err_page != nil{
return
}
defer rows.Close()
//数据添加到 集合中
for rows.Next(){
var store Store
rows.Scan(&store.Id, &store.Code, &store.Name,&store.CompanyId,&store.OpenStatus,&store.HoursDesc)
stores = append(stores,store)
}
}else{
rows, err_page := db.SqlDB.Query(“select id,name,company_id,code,open_status,hours_desc from store limit ?,?”,(page-1)*pageSize, pageSize)
if err_page != nil{
return
}
defer rows.Close()
//数据添加到 集合中
for rows.Next(){
var store Store
rows.Scan(&store.Id, &store.Code, &store.Name,&store.CompanyId,&store.OpenStatus,&store.HoursDesc)
stores = append(stores,store)
}
}
return
}
//获取查询条数 循环遍历 累加
func GetStoreNum(searchStr string) (nums int){
num := 0
if searchStr != “”{
rows, err_nums := db.SqlDB.Query(“select id from store where name like '%”+searchStr+"%’")
if err_nums != nil{
return 0
}
defer rows.Close()
for rows.Next(){
num++;
}
}else{
rows, err_nums := db.SqlDB.Query(“select id from store”)
if err_nums != nil{
return 0
}
defer rows.Close()
for rows.Next(){
num++;
}
}
return num
}
数据库连接池目录 databases/mysql.go-------------------------
package databases
import (
“database/sql”
_ “github.com/go-sql-driver/mysql”
“log”
)
//使用sql.Open()方法会创建一个数据库连接池db。这个地步不是数据库连接,它是一个连接池,只有当真正的数据库通信的时候才创建连接。例如,这里的db.Ping()操作。db.SetMaxIdleConns(20)和db.SetMaxOpenConns(20)分别设置数据库的空闲连接和最大打开连接,即向Mysql服务端发出的所有连接的最大数目。
//因为我们需要在其他地方使用SqlDB这个变量,所以需要大写代表public
var SqlDB *sql.DB

func init() {
var err error
SqlDB, err = sql.Open(“mysql”, “root:root@tcp(127.0.0.1:3306)/fk_dev?parseTime=true”)
if err != nil{
log.Fatalln(err.Error())
}
//连接检测
err = SqlDB.Ping()
if err != nil{
log.Fatalln(err.Error())
}
}

API层(controller层)---------------------------------------
api接口目录的store.go 后面加入controller层(StoreController.go)
其中 store.go 文件:
package api
import (
“fkHalo/models”
“github.com/gin-gonic/gin”
“log”
“net/http”
“strconv”
)

func Index(c *gin.Context) {
c.String(http.StatusOK, “首页Index is ok”)
}
//获取所有门店列表
func GetAllStores(c *gin.Context){
var store models.Store
stores, err := store.GetStores()
if err != nil{
log.Fatalln(err)
}
c.JSON(http.StatusOK, gin.H{
“total”:len(stores),
“list”:stores,
})
}
效果 :
http://localhost:5050/get_all_stores
{“list”:[{“id”:280,“name”:“63”,“company_id”:“bp0hhf96jpcv3kj41mtg”,“code”:“测试门店”,“open_status”:1,“hours_desc”:“全天24小时”}

{“id”:286,“name”:“63”,“company_id”:“bp1u3m96jpcv3kj41n50”,“code”:“测试门店1”,“open_status”:0,“hours_desc”:""}],“total”:7}

//获取所有门店列表 查询id来获取总数
func GetStoresLists(c *gin.Context){
//获取列表
var store models.Store
stores, err := store.GetStores()
if err != nil{
log.Fatalln(err)
}
// 获取总数 搜索了很多资料 貌似gin没有count查询函数
var storeIds models.Store
storeIdsArr, err := storeIds.GetStoreTotal()
if err != nil{
log.Fatalln(err)
}
c.JSON(http.StatusOK, gin.H{
“total”:len(storeIdsArr),
“list”:stores,
})
}
效果:
http://localhost:5050/get_stores
{“list”:[{“id”:280,“name”:“63”,“company_id”:“bp0hhf96jpcv3kj41mtg”,“code”:“测试门店”,“open_status”:1,“hours_desc”:“全天24小时”}

{“id”:286,“name”:“63”,“company_id”:“bp1u3m96jpcv3kj41n50”,“code”:“测试门店1”,“open_status”:0,“hours_desc”:""}],“total”:7}
//获取所有门店列表 带分页
func GetStoresListsByPage(c *gin.Context){
page := c.Param(“page”)
pageSize := c.Param(“pageSize”)
seachKey := c.Param(“seachKey”)
pageInt, err := strconv.Atoi(page)
pageSizeInt, err := strconv.Atoi(pageSize)
if err != nil{
log.Fatalln(err)
}
//获取分页列表
stores, err := models.GetStoresByPage(pageInt,pageSizeInt,seachKey)
if err != nil {
log.Fatalln(err)
}
//获取总数
total := models.GetStoreNum(seachKey)
c.JSON(http.StatusOK, gin.H{
“page”:page,
“pageSize”:pageSize,
“seachKey”:seachKey,
“total”:total,
“list”:stores,
})
}
效果:
http://localhost:5050/get_stores_page/1/10/测试
{“list”:[{“id”:280,“name”:“63”,“company_id”:“bp0hhf96jpcv3kj41mtg”,“code”:“测试门店”,“open_status”:1,“hours_desc”:“全天24小时”},

{“id”:286,“name”:“63”,“company_id”:“bp1u3m96jpcv3kj41n50”,“code”:“测试门店1”,“open_status”:0,“hours_desc”:""}],“page”:“1”,“pageSize”:“10”,“seachKey”:“测试”,“total”:3}

Controller层的StoreController.go 如下:
package controller
import (
“fkHalo/models”
“fmt”
“github.com/gin-gonic/gin”
“log”
“net/http”
“strconv”
)
func StoreGetAllStores(c *gin.Context) {
page := c.Query(“page”)
pageSize := c.Query(“pageSize”)
searchKey := c.Query(“searchKey”)
pageInt, err := strconv.Atoi(page)
pageSizeInt, err := strconv.Atoi(pageSize) //字符串转数字
if err != nil{
log.Fatalln(err)
}
//获取分页列表
fmt.Print(pageInt) //打印参数
fmt.Print(pageSizeInt)
fmt.Print(searchKey)
stores, err := models.GetStoresByPage(pageInt,pageSizeInt,searchKey)
if err != nil {
log.Fatalln(err)
}
//获取总数
total := models.GetStoreNum(searchKey)
c.JSON(http.StatusOK, gin.H{
“page”:page,
“pageSize”:pageSize,
“seachKey”:searchKey,
“total”:total,
“list”:stores,
})
}
http://localhost:5050/store/get_stores_list_page?page=1&pageSize=10&searchKey=测试
结果:
{“list”:[{“id”:280,“name”:“63”,“company_id”:“bp0hhf96jpcv3kj41mtg”,“code”:“测试门店”,“open_status”:1,“hours_desc”:“全天24小时”},{“id”:286,“name”:“63”,“company_id”:“bp1u3m96jpcv3kj41n50”,“code”:“测试门店1”,“open_status”:0,“hours_desc”:""}],“page”:“1”,“pageSize”:“10”,“seachKey”:“测试”,“total”:3}

备注:因为gin框架无法直接查询Count总数或框架写法,找了一上午也没太多发现,目前有两种解决办法:1.获取所有列表 用len()方法;2.获取所有列表后循环累加++ 如果数据量大了可能会有内存问题,所以还需要放大招:引用(使用)Gorm;欢迎大家指正和建议;

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值