• go编写简单接口的过程


    环境

    系统

    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
    ", 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
  • 相关阅读:
    centos7搭建kvm
    python脚本与shell脚本的结合应用
    shell脚本常用命令组合
    服务器硬盘损坏恢复过程
    linux grup引导进入单用户下
    mysql 数据库设计查询规范
    mysql 8.0 远程连接问题
    linux新加硬盘的操作
    linux 添加硬盘到/home 目录
    linux设置最大连接数
  • 原文地址:https://www.cnblogs.com/sentangle/p/12170493.html
Copyright © 2020-2023  润新知