环境

系统

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. 【k8s】kubeadm快速部署Kubernetes

    1.Kubernetes 架构图 kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Mast ...

  2. 微信小程序酒店日历超强功能

    首先利用date拿到年月日 月记得+1 ,因为是从0开始的 先遍历月份,跨年年+1 ,月归至1: 然后遍历天数, lastDat = new Date(val.year,val.month,0).ge ...

  3. python中交换两个变量值的方法

    a = 4b = 5 #第1种c = 0c = aa = bb = c #第2种a = a+bb = a-ba = a-b #第3种a,b = b,a print("a=%d,b=%d&qu ...

  4. 第四阶段:1.从零打造一款社区web产品

    ---恢复内容开始--- 熟人关系:微信 陌生人关系:微博 1.把各种竞品罗列起来形成一个分析池.分析其目标用户是哪些.这些产品满足了用户什么需求.可以从时间角度分析趋势.针对每一类竞品画一个商业模式 ...

  5. JS事件之自建函数bind()与兼容性问题解决

    JavaScript事件绑定常用方法 对象.事件 = 函数; 它只能同时为一个对象的一个事件绑定一个响应函数 不能绑定多个,如果有多个,后面的会覆盖前面的 addEventListener() 此方法 ...

  6. 【萌新向】cartographer_ros最新安装指南 2019-12

    首先说明,这篇文章于2019年12月写下,cartographer现在还在不断更新,也许这篇文档内容会失效,但是大体是一样的安装流程. 一.硬件条件 使用平台 x86_64平台 ROS发行版 Indi ...

  7. requests库结合selenium库共同完成web自动化和爬虫工作

    我们日常工作中,单纯的HTTP请求,程序员都倾向于使用万能的python Requests库.但大多数场景下,我们的需求页面不是纯静态网页,网页加载过程中伴随有大量的JS文件参与页面的整个渲染过程,且 ...

  8. hexo+next 详细搭建

    安装node node下载地址:http://nodejs.cn/download/ 具体安装方法,这里不做详写 安装完成可以通过node -v 查看安装是否生效和node的版本 我这里使用的是v10 ...

  9. k8s集群———flannel网络

    #master执行将内网通信地址写入etcd中,确保flannel能与etcd通信 #添加 /opt/etcd/bin/etcdctl --ca-file=/opt/etcd/ssl/ca.pem - ...

  10. ElementUi 表格取消全选框,用文字表示

    Echarts ElementUi 表格取消全选框,用文字表示 1.先看看实现的图 一. 添加添加复选框列 <el-table v-loading="zongShipLoading&q ...