环境

系统

Windows server 2016 Datacener

go version

go1.13.3 windows/amd64

数据库

Microsoft SQL Server 2014(64位)

基本构成

接口代码使用扩展类库

"crypto/md5"
"encoding/json"
"fmt"
_ "github.com/denisenkom/go-mssqldb"
"github.com/gin-gonic/gin"
"github.com/go-xorm/xorm"
"github.com/satori/go.uuid"

gin web框架 负责web服务器及路由请求处理

xorm和go-mssqldb 数据库对象orm处理

go.uuid 生成uuid标识

代码

main.go

package main

import (
"crypto/md5"
"encoding/json"
"fmt"
_ "github.com/denisenkom/go-mssqldb"
"github.com/gin-gonic/gin"
"github.com/go-xorm/xorm"
"github.com/satori/go.uuid"
) func main() { //关闭gin debug
gin.SetMode(gin.ReleaseMode)
router := gin.Default() //提交生产api
router.POST("/test", productionOrderHandler)
//测试api是否正常访问
router.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
}) router.Run(":8080")
} /**
获取uuid
*/
func GetUuid() string {
// or error handling
val, err := uuid.NewV4()
if err != nil {
panic("生成uuid错误:"+err.Error())
}
return val.String()
} /**
md函数
*/
func GetMd5(str string) string { hash := md5.New()
hash.Write([]byte(str))
result := hash.Sum([]byte(""))
return fmt.Sprintf("%x",result)
} /**
提交生产逻辑
*/
func productionOrder(orderNo interface{}, orderMap []interface{}, booksMap []interface{}, engineDb *xorm.Engine) (bool, string) { message := "执行成功"
//事务开启
session := engineDb.NewSession()
defer session.Close()
//4.1 pm_order表
var orderData pm_order
for _, item := range orderMap {
// 类型转换
orderItem := item.(map[string]interface{})
orderData.Key_seq = GetUuid()
//此处隐藏数据结构
if _, err := engineDb.Insert(orderData); err != nil {
session.Rollback()
message = "pm_order添加数据失败:" + err.Error()
return false, message
}
}
//4.2 pm_order表 PM_OrderStatus表 PM_OrderStatusDetail表
var bookData pm_books
var orderStatusData pm_orderstatus
var orderStatusDetailData pm_orderstatusdetail
for _, item := range booksMap {
// 类型转换
bookItem := item.(map[string]interface{})
//4.2.1 pm_order数据处理
bookData.Key_seq = GetUuid()
//此处隐藏数据结构
//4.2.2 PM_OrderStatus数据处理
orderStatusData.Orderno = bookItem["OrderNo"].(string)
//此处隐藏数据结构
//4.2.3 PM_OrderStatusDetail表
orderStatusDetailData.Orderno = bookItem["OrderNo"].(string)
//此处隐藏数据结构 if _, err := engineDb.Insert(bookData, orderStatusData, orderStatusDetailData); err != nil {
session.Rollback()
message = "pm_books/pm_orderstatus/pm_orderstatusdetail添加数据失败:" + err.Error()
return false, message
}
} session.Commit() return true, message
} func productionOrderHandler(c *gin.Context) {
message := "未知错误"
//c.Request.ParseForm()
//for k, v := range c.Request.PostForm {
// fmt.Printf("%v=>%v\n", k,v)
//}
//c.String(200, message)
//return //验证数据合法性
orderInfoJson := c.PostForm("OrderInfo")
if false {
message = "验证数据合法性失败"
c.String(200, message)
return
} //1.获取post数据并解析
var orderInfo map[string]interface{}
// 解析字符串为Json
json.Unmarshal([]byte(orderInfoJson), &orderInfo)
//转换成map对象
orderMap := orderInfo["PM_Order"].([]interface{})
booksMap := orderInfo["PM_Books"].([]interface{})
if orderMap == nil || booksMap == nil{
message = "数据json解析失败"
c.String(200, message)
return
}
var orderNo string
for _, item := range orderMap {
// 类型转换
orderItem := item.(map[string]interface{})
orderNo = orderItem["OrderNo"].(string)
if orderNo == "" {
message = "数据json解析失败:orderno解析失败"
c.String(200, message)
return
}
} //2 建立连接
var dbConfig = [...]string{
"127.0.0.1",
"sa",
"123456",
"test",
}
//fmt.Println(dbConfig)
//c.String(200, message)
//return connString := fmt.Sprintf("server=%s;port%d;user id=%s;password=%s;database=%s;", dbConfig[0], 1433, dbConfig[1], dbConfig[2], dbConfig[3])
engineDb, err := xorm.NewEngine("mssql", connString)
if err != nil {
message = "连接数据库失败"
c.String(200, message)
return
}
//3 检查订单是否已提交,已提交则返回成功
has, err := engineDb.SQL("select * from PM_Order where orderNo = ?", orderNo).Exist()
if err != nil {
message = "数据查询失败"
c.String(200, message)
return
}
if has {
c.String(200, "ok")
return
}
//4.开始提交订单数据
result, errmsg := productionOrder(orderNo, orderMap, booksMap, engineDb)
if result == false {
c.String(200, errmsg)
return
}
c.String(200, "ok")
return
}

com_model.go

/**
数据库对应的struct
*/
package main
import "time"
//PM_Order表
type pm_order struct {
Key_seq string
...
}
//PM_Books表
type pm_books struct { Key_seq string
Orderno string
... }
//PM_OrderStatus表
type pm_orderstatus struct {
Orderno string
...
Updatetime time.Time `xorm:"created"`
}
//PM_OrderStatusDetail表
type pm_orderstatusdetail struct {
Key_seq string
...
Createtime time.Time `xorm:"created"`
}

可执行文件压缩

使用upx打压缩壳, upx 下载地址 https://upx.github.io/

编译无符号表和调试信息的可执行文件

go build -ldflags "-s -w"

调用upx压缩

upx.exe -9 ginTest.exe

go编写简单接口的过程的更多相关文章

  1. Hadoop基础-MapReduce入门篇之编写简单的Wordcount测试代码

    Hadoop基础-MapReduce入门篇之编写简单的Wordcount测试代码 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本文主要是记录一写我在学习MapReduce时的一些 ...

  2. 使用Flask开发简单接口

    作为测试人员,在工作或者学习的过程中,有时会没有可以调用的现成的接口,导致我们的代码没法调试跑通的情况. 这时,我们使用python中的web框架Flask就可以很方便的编写简单的接口,用于调用或调试 ...

  3. 【转】用systemJS+karma+Jasmine+babel环境去编写简单的ES6工程

    原文链接:http://www.cnblogs.com/shuoer/p/7779131.html 用systemJS+karma+Jasmine+babel环境去编写简单的ES6工程 首先解释下什么 ...

  4. SLAM+语音机器人DIY系列:(二)ROS入门——6.编写简单的service和client

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  5. Java开发笔记(五十八)简单接口及其实现

    前面介绍了抽象方法及抽象类的用法,看似解决了不确定行为的方法定义,既然叫唤动作允许声明为抽象方法,那么飞翔.游泳也能声明为抽象方法,并且鸡类涵盖的物种不够多,最好把这些行为动作扩展到鸟类这个群体,于是 ...

  6. .NET Core微服务之路:利用DotNetty实现一个简单的通信过程

    上一篇我们已经全面的介绍过<基于gRPC服务发现与服务治理的方案>,我们先复习一下RPC的调用过程(笔者会在这一节的几篇文章中反复的强调这个过程调用方案),看下图

  7. day1作业:编写登陆接口

    作业一:编写登陆接口 1.输入用户名和密码 2.认证成功后显示欢迎信息 3.输错三次后锁定 思路:要求是编写登陆接口,那么要有一个存放用户信息的模块:三次后锁定,要有一个存放锁定用户信息的模块:我们知 ...

  8. C++编写简单的俄罗斯方块游戏

    代码地址如下:http://www.demodashi.com/demo/14593.html C++编写简单的俄罗斯方块游戏 使用C++编写一个简单的俄罗斯方块游戏. 1 环境要求 使用C++图形库 ...

  9. 学习 Linux,101: 自定义或编写简单脚本【转】

    转自:http://www.ibm.com/developerworks/cn/linux/l-lpic1-105-2/index.html 学习如何使用标准的 shell 语法.循环和控制结构,以及 ...

随机推荐

  1. 2019 ICPC 陕西西安邀请赛 D. Miku and Generals

    传送门:https://nanti.jisuanke.com/t/39271 题意: 给你n个人,每个人有一个权值 a_i ​,(a_i​是可以被100整除的))现在需要你将n个人分成两组,有m个关系 ...

  2. jedis 连接池工具类

    maven <properties> <jedis.version>3.0.1</jedis.version> <junit.verion>4.12&l ...

  3. 学习Java第三周

    这是学习java的第三周 上周想要学习的这周也完成了,研究和测试代码花费了大约2个小时,发现这些内容方法居多,想要熟练掌握就要好好记忆了 包装类 数字处理类 Object类 Java类包 内部类 下一 ...

  4. pytorch中DataLoader, DataSet, Sampler之间的关系

    转自:https://mp.weixin.qq.com/s/RTv0cUWvc0kuXBeNoXVu_A 自上而下理解三者关系 首先我们看一下DataLoader.__next__的源代码长什么样,为 ...

  5. 使用 postman 给 API 写测试

    使用 postman 给 API 写测试 Intro 上次我们简单介绍了 使用 postman 测试 API,这次主要来写一些测试用例以检查请求的响应是否符合我们的预期以及如何使用脚本测试 使用 po ...

  6. 013 CephFS文件系统

    一.Ceph文件系统简介 CephFS提供兼容POSIX的文件系统,将其数据和与那数据作为对象那个存储在Ceph中 CephFS依靠MDS节点来协调RADOS集群的访问 元数据服务器 MDS管理元数据 ...

  7. $CF949D\ Curfew$ 二分/贪心

    正解:二分/贪心 解题报告: 传送门$QwQ$ 首先这里是二分还是蛮显然的?考虑二分那个最大值,然后先保证一个老师是合法的再看另一个老师那里是否合法就成$QwQ$. 发现不太会搞这个合不合法的所以咕了 ...

  8. $bzoj2560$ 串珠子 容斥+$dp$

    正解:容斥+$dp$ 解题报告: 传送门$QwQ$ $umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多 ...

  9. 使用ASP.NET Core 3.x 构建 RESTful API - 4.2 过滤和搜索

    向Web API传递参数 数据可以通过多种方式来传给API. Binding Source Attributes 会告诉 Model 的绑定引擎从哪里找到绑定源. 共有以下六种 Binding Sou ...

  10. 《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态

    1. 简介 今天北京下的雪好大好美啊!!!哎呀,忘记拍照片了,自己想象一下吧.言归真传,今天还是开始pytest的学习和修炼,上一篇写完后群里反响各式各样的,几家欢乐几家愁,有的高兴说自己刚好要用到了 ...