环境

系统

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. Team Foundation Server 2015使用教程【8】:读取器tfs组的checkin权限修改

  2. TDengine 时序数据库的 ADO.Net Core 提供程序 Maikebing.EntityFrameworkCore.Taos

    简介 Entity, Framework, EF, Core, Data, O/RM, entity-framework-core,TDengine Maikebing.Data.Taos 是一个基于 ...

  3. 【译】PEP 318--函数和方法的装饰器

    PEP原文 : https://www.python.org/dev/peps/pep-0318 PEP标题: Decorators for Functions and Methods PEP作者: ...

  4. Java工程师阅读源码的一些见解

    一.为何阅读源码 就是说,通过阅读源码能给你带来什么好处. 学习如何从需求-设计-实现,开阔你的思维,提升你的架构设计能力: 帮助更好地理解原理和架构设计: 帮助更快地定位线上问题BUG 可以根据自己 ...

  5. 洛谷P2858 奶牛零食 题解 区间DP入门题

    题目大意: 约翰经常给产奶量高的奶牛发特殊津贴,于是很快奶牛们拥有了大笔不知该怎么花的钱.为此,约翰购置了 \(N(1 \le N \le 2000)\) 份美味的零食来卖给奶牛们.每天约翰售出一份零 ...

  6. 洛谷P1427 小鱼的数字游戏 题解 递归入门题

    题目链接:https://www.luogu.com.cn/problem/P1427 题目大意: 给你一串数(输入到0为止),倒序输出这些数. 解题思路: 首先这道题目可以用数组存数据,然后输出. ...

  7. iscsi,nfs

    存储概述 存储的目标 存储是根据不同的应用环境通过采取合理.安全.有效的方式将数据保存到某些介质上并能保证有效的访问. 一方面它是数据临时或长期驻留的物理媒介. 另一方面,它是保证数据完整安全存放的方 ...

  8. vmware workstation12在安装VMware tools时出现问题:A previous installation of VMware Tools has been detected 解决

    win10安装的vmware workstation12在安装VMware tools时出现问题: root@lc:/root/vmware-tools-distrib# ./vmware-insta ...

  9. 《提升能力,涨薪可待》—Java并发之Synchronized

    Synchronized简介 线程安全是并发编程中的至关重要的,造成线程安全问题的主要原因: 临界资源, 存在共享数据 多线程共同操作共享数据 而Java关键字synchronized,为多线程场景下 ...

  10. 【转】15个超炫的HTML5效果

    英文原文:http://www.hongkiat.com/blog/15-html5-experiments/     翻译:iteye 乔布斯没有给Flash任何机会,微软新推出的Windows 8 ...