这篇主要学习go项目中的项目结构、项目规范等知识,ROM采用的database/sql的写法。

1.技术框架

利用的是ginweb框架,然后ROM层选用database/sql,安装mysql驱动。安装方式如下:

//使用github上的gin托管地址

$ go get -u github.com/gin-gonic/gin

$ go get github.com/go-sql-driver/mysql

2.项目结构如下

项目结构分析:

1、main.go主要是存放路由,启动项目;

2、router主要存放路由信息,然后返回一个router;

3、apis存放router的Handler函数;

4、databases存放数据连接信息;

5、models存放数据模型,类似Java中POJO对象。

│ main.go

├─.idea

│ │ go.iml

│ │ misc.xml

│ │ modules.xml

│ │ workspace.xml

│ │

│ └─inspectionProfiles

├─apis

│ person.go

├─databases

│ mysql.go

├─models

│ person.go

└─router

router.go

image.png

3.main.go代码解释

package main

import (

//这里讲db作为go/databases的一个别名,表示数据库连接池

db "go/databases"

. "go/router"

)

func main() {

//当整个程序完成之后关闭数据库连接

defer db.SqlDB.Close()

router := InitRouter()

router.Run(":8080")

}

4.router.go代码解释

package router

import (

"github.com/gin-gonic/gin"

."go/apis"

)

func InitRouter() *gin.Engine {

router := gin.Default()

//IndexApi为一个Handler

router.GET("/", IndexApi)

router.POST("/person", AddPersonApi)

router.GET("/persons", GetPersonsApi)

router.GET("/person/:id", GetPersonApi)

router.PUT("/person/:id", ModPersonApi)

router.DELETE("/person/:id", DelPersonApi)

return router

}

5.mysql.go代码解释

package databases

import (

"database/sql"

_ "github.com/go-sql-driver/mysql"

"log"

)

//因为我们需要在其他地方使用SqlDB这个变量,所以需要大写代表public

var SqlDB *sql.DB

//初始化方法

func init() {

var err error

SqlDB, err = sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?parseTime=true")

if err != nil {

log.Fatal(err.Error())

}

//连接检测

err = SqlDB.Ping()

if err != nil {

log.Fatal(err.Error())

}

}

使用sql.Open()方法会创建一个数据库连接池db。这个地步不是数据库连接,它是一个连接池,只有当真正的数据库通信的时候才创建连接。例如,这里的db.Ping()操作。db.SetMaxIdleConns(20)和db.SetMaxOpenConns(20)分别设置数据库的空闲连接和最大打开连接,即向Mysql服务端发出的所有连接的最大数目。

6.models中person.go代码解释

package models

import (

"log"

db "go/databases"

)

//定义person类型结构

type Person struct {

Id int `json:"id"`

FirstName string `json:"first_name"`

LastName string `json:"last_name"`

}

func (p *Person) AddPerson() (id int64, err error) {

rs, err := db.SqlDB.Exec("INSERT INTO person(first_name, last_name) VALUES (?, ?)", p.FirstName, p.LastName)

if err != nil {

return

}

id, err = rs.LastInsertId()

return

}

func (p *Person) GetPersons() (persons []Person, err error) {

persons = make([]Person, 0)

rows, err := db.SqlDB.Query("SELECT id, first_name, last_name FROM person")

defer rows.Close()

if err != nil {

return

}

for rows.Next() {

var person Person

rows.Scan(&person.Id, &person.FirstName, &person.LastName)

persons = append(persons, person)

}

if err = rows.Err(); err != nil {

return

}

return

}

func (p *Person) GetPerson() (person Person, err error) {

err = db.SqlDB.QueryRow("SELECT id, first_name, last_name FROM person WHERE id=?", p.Id).Scan(

&person.Id, &person.FirstName, &person.LastName,

)

return

}

func (p *Person) ModPerson() (ra int64, err error) {

stmt, err := db.SqlDB.Prepare("UPDATE person SET first_name=?, last_name=? WHERE id=?")

defer stmt.Close()

if err != nil {

return

}

rs, err := stmt.Exec(p.FirstName, p.LastName, p.Id)

if err != nil {

return

}

ra, err = rs.RowsAffected()

return

}

func (p *Person) DelPerson() (ra int64, err error) {

rs, err := db.SqlDB.Exec("DELETE FROM person WHERE id=?", p.Id)

if err != nil {

log.Fatalln(err)

}

ra, err = rs.RowsAffected()

return

}

执行非query操作,使用db的Exec方法,在MySQL中使用?做占位符。最后我们把插入后的Id返回给客户端。

GetPersons方法解释:

读取MySQL的数据需要有一个绑定的过程,db.Query()方法返回一个rows对象,这个数据库连接随即转移到这个对象,因此我们需要定义rows.Close()操作,然后创建一个[]Person的切片。

使用make,而不是直接使用var persons []Person的声明方式。还是有所差别的,使用make的方式,当数组切片没有元素的时候,Json会返回[]。如果直接声明,json会返回null。

接下来就是使用rows对象的Next()方法,遍历所查询的数据,一个个绑定到person对象上,最后append到person切片。

7.apis中的person.go代码解释

package apis

import (

"net/http"

"log"

"fmt"

"strconv"

"github.com/gin-gonic/gin"

."go/models"

)

func IndexApi(c *gin.Context) {

c.String(http.StatusOK, "It works")

}

func AddPersonApi(c *gin.Context) {

firstName := c.Request.FormValue("first_name")

lastName := c.Request.FormValue("last_name")

p := Person{FirstName: firstName, LastName: lastName}

ra, err := p.AddPerson()

if err != nil {

log.Fatalln(err)

}

msg := fmt.Sprintf("insert successful %d", ra)

c.JSON(http.StatusOK, gin.H{

"msg": msg,

})

}

func GetPersonsApi(c *gin.Context) {

var p Person

persons, err := p.GetPersons()

if err != nil {

log.Fatalln(err)

}

c.JSON(http.StatusOK, gin.H{

"persons": persons,

})

}

func GetPersonApi(c *gin.Context) {

cid := c.Param("id")

id, err := strconv.Atoi(cid)

if err != nil {

log.Fatalln(err)

}

p := Person{Id: id}

person, err := p.GetPerson()

if err != nil {

log.Fatalln(err)

}

c.JSON(http.StatusOK, gin.H{

"person": person,

})

}

func ModPersonApi(c *gin.Context) {

cid := c.Param("id")

id, err := strconv.Atoi(cid)

if err != nil {

log.Fatalln(err)

}

p := Person{Id: id}

err = c.Bind(&p)

if err != nil {

log.Fatalln(err)

}

ra, err := p.ModPerson()

if err != nil {

log.Fatalln(err)

}

msg := fmt.Sprintf("Update person %d successful %d", p.Id, ra)

c.JSON(http.StatusOK, gin.H{

"msg": msg,

})

}

func DelPersonApi(c *gin.Context) {

cid := c.Param("id")

id, err := strconv.Atoi(cid)

if err != nil {

log.Fatalln(err)

}

p := Person{Id: id}

ra, err := p.DelPerson()

if err != nil {

log.Fatalln(err)

}

msg := fmt.Sprintf("Delete person %d successful %d", id, ra)

c.JSON(http.StatusOK, gin.H{

"msg": msg,

})

}

其实,整个项目的结构和CRUD操作跟Java中的思想比较类似,应该很容易上手。需要注意一点的是,如果需要将整个项目运行起来,项目的路径一定Gopath路径:F:\Go\Project\src;

image.png

image.png

项目启动结果如下:

image.png

熟悉了database/sql的写法后,下一步就是学习ROM框架gorm的写法,进而学习Docker进行部署。

参考资料

ginapi服务器性能,基于gin web框架搭建RESTful API服务相关推荐

  1. 使用CodeIgniter框架搭建RESTful API服务

    RESTful不仅仅是一套协议标准更是一种设计思路. 在2011年8月的时候,我写了一篇博客<使用CodeIgniter框架搭建RESTful API服务>,介绍了RESTful的设计概念 ...

  2. Docker——基于HubServing部署全套PaddleOCR Restful API服务(CPU版本)

    说明 1.同时部署ocr_det.ocr_cls.ocr_rec.ocr_system 2.基于https://gitee.com/paddlepaddle/PaddleOCR/blob/v2.0.0 ...

  3. Spring Cloud——基于OpenFeign调用PaddleOCR的Restful API服务解决方案

    PaddleOCR的Restful API服务部属 Docker化部署服务 PaddleOCR--Docker环境下基于HubServing模式部署Restful API服务(CPU版本) Maven ...

  4. Python之简易Web框架搭建

    Python之简易Web框架搭建 Web框架介绍 WSGI协议 Web框架开发 项目结构 MyWebServer.py 之前的静态服务器代码 WSGI协议的要求 更新代码 framework.py 返 ...

  5. git web框架搭建_Git,Python Web框架,AI,机器学习,Android,Linux和更多必读内容

    git web框架搭建 上周最受关注的是Kedar Vijay Kulkarni编写的新Git系列中的最新一期,随后是Nicholas Hunt-Walker编写的 Python Web框架系列中的最 ...

  6. 基于springboot+mybatis-plus框架搭建的校园食堂订餐系统

    基于springboot+mybatis-plus框架搭建的校园食堂订餐系统 客户登陆界面 视频链接 部分主界面 购物车界面 管理员界面(也可称为用户) 视频链接 商品管理界面

  7. PaddleOCR——Docker环境下基于HubServing模式部署Restful API服务(CPU版本)

    Docker环境下基于HubServing模式部署Restful API服务(CPU版本) 在日常项目应用中,相信大家一般都会希望能通过Docker技术,把PaddleOCR服务打包成一个镜像,以便在 ...

  8. ginapi服务器性能,gin框架构建Api之:环境配置和路由

    Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,已经发布了1.0版本.具有快速灵活,容错方便等特点.其实对于golang而言,web框架的依赖要远比Python,Java ...

  9. ginapi服务器性能,如何使用 Gin 和 Gorm 搭建一个简单的 API 服务 (一)

    gin-gonic 介绍 Go 语言最近十分火热,但对于新手来说,想立马上手全新的语法和各种各样的框架还是有点难度的.即使是基础学习也很有挺有挑战性. 在这篇文章中,我想用最少的代码写出一个可用的 A ...

最新文章

  1. 计算机培训操作规程,电脑裁床操作规程
  2. mysql tomcat 自动重连_基于tomcat+mysql的c/s模式下的系统自动更新
  3. 软件详细设计说明书_校导周绪龙|软件测试第五篇——软件测试的底层思维
  4. GoldenGate系统三:trouble shooting and log
  5. MySQL基础原创笔记(一)
  6. PowerShell(PHPStorm terminal with PowerShell)运行git log中文乱码
  7. 等压线上怎么画风向_圣诞贺卡怎么写?向你爱的人送上最有温度的祝福吧!
  8. Atitit 提升开发效率使用内嵌Tomcat 内嵌webserver 于单元测试
  9. 百度顶会论文复现营论文心得
  10. built a JNCIS LAB系列:Chapter 7 MPLS
  11. 【vbers】ibv_post_send|IBV_SEND_SOLICITED|RDMA
  12. Hyper-V虚拟化——在Hyper-V上创建虚拟服务器
  13. Android 购物选择颜色、尺码实现
  14. java 流读取图片供前台显示
  15. 液压传动基础知识(一)
  16. 重邮2019计算机复试准备工作相关
  17. 站长得知道的九种工具
  18. phpwind源码解析------index.php
  19. 感悟西游记——成气候的妖精都是领导家的
  20. 建议阿里巴巴10亿回购股票救市

热门文章

  1. Hack微信,不一样的安全视角
  2. 【阿里云】深入分析阿里云中图片服务的架构经验
  3. 2021-11-29 轨迹规划五次多项式
  4. MATLAB代码编写中自定义变量的问题
  5. echarts 多种类型的legend一行居中展示
  6. 【SAP】ABAP——小币种转换
  7. HLOJ 1936 铺满方格
  8. 新浪微博应用开发入门
  9. ZooKeeper之服务器地址列表。
  10. c语言大作业开题报告,C语言大作业报告.doc