云起工作室 15711107967
微信开发-关注登录

1、二维码页面,请求接口获取 logincode 和二维码地址页面保存 logincode ,此logincode将会成为登录标识符2 、二维码接口 生成logincode,获取二维码地址返回给二维码页面3、微信扫描二维码,微信会向服务器以post方式发送消息 ,此接口通过微信公众平台启用服务器配置的接口 配置接口获取数据中有 FromUserName 这就是openid;EventKey 是带qrscene_前缀的loginCode通过loginCode := strings.TrimPrefix(msg.EventKey, "qrscene_") 获取loginCode通过openid,查询、创建用户,将loginCode以登录标识保存起来const ( token = "tianwanggaidihu" // 替换为自己在微信公众号设置的 Token,配置服务器时自定义填写的)type AccessTokenResponse struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"` ErrCode int `json:"errcode"` ErrMsg string `json:"errmsg"`}type QRCodeTicketResponse struct { Ticket string `json:"ticket"` ExpireSeconds int `json:"expire_seconds"` URL string `json:"url"` ErrCode int `json:"errcode"` ErrMsg string `json:"errmsg"`}// 添加消息结构体 推送的消息结构体type TextMessage struct { ToUser string `json:"touser"` MsgType string `json:"msgtype"` Text struct { Content string `json:"content"` } `json:"text"`}接口1、//get请求,用于配置时的验证,验证通过后就没用了func (ct *WeixinController) Fromweixinplat(ctx *gin.Context) { signature := ctx.Query("signature") timestamp := ctx.Query("timestamp") nonce := ctx.Query("nonce") echostr := ctx.Query("echostr") // 1. 将 token、timestamp、nonce 三个参数进行字典序排序 strs := sort.StringSlice{token, timestamp, nonce} sort.Strings(strs) // 2. 将三个参数字符串拼接成一个字符串进行 sha1 加密 str := strings.Join(strs, "") h := sha1.New() h.Write([]byte(str)) sha1Sum := fmt.Sprintf("%x", h.Sum(nil)) // 3. 将加密后的字符串与 signature 进行对比 return sha1Sum == signature if sha1Sum == signature { ctx.String(200, echostr) } else { ctx.String(403, "验证失败") } return}接口22.1、// 展现二维码的页面请求的接口:生成登录二维码 func (ct *WeixinController) GenerateLoginQRCode(ctx *gin.Context) { backData := Tools.BackData{} // 生成唯一登录码 loginCode := fmt.Sprintf("%d", time.Now().UnixNano()) // 获取access_token accessToken, err := ct.getAccessToken() if err != nil { ctx.JSON(500, gin.H{"error": "获取access_token失败"}) return } // 获取二维码ticket ticket, err := ct.getQRCodeTicket(accessToken, loginCode) if err != nil { ctx.JSON(500, gin.H{"error": "获取二维码ticket失败"}) return } rdb := Tools.GetRedis() // 存储登录码(设置5分钟过期) err = rdb.Set("login:"+loginCode, "pending", 5*time.Minute).Err() if err != nil { ctx.JSON(500, gin.H{"error": "生成登录码失败"}) return } // 返回登录码和二维码链接 // 注意:这里需要替换为你的公众号二维码链接 qrcodeURL := fmt.Sprintf("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s&scene=%s", ticket, loginCode) ctx.JSON(200, gin.H{ "code": loginCode, //页面存储的 "qrcode_url": qrcodeURL, //将qrcodeRRL 放到img src属性 }) }2.2、// 获取二维码ticketfunc (ct *WeixinController) getQRCodeTicket(accessToken, sceneStr string) (string, error) { url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s", accessToken) // 构造请求数据 data := map[string]interface{}{ "expire_seconds": 604800, // 7天有效期 "action_name": "QR_STR_SCENE", "action_info": map[string]interface{}{ "scene": map[string]string{ "scene_str": sceneStr, }, }, } jsonData, err := json.Marshal(data) if err != nil { return "", err } resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData)) if err != nil { return "", err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } var ticketResp QRCodeTicketResponse if err := json.Unmarshal(body, &ticketResp); err != nil { return "", err } if ticketResp.ErrCode != 0 { return "", fmt.Errorf("获取二维码ticket失败:%s", ticketResp.ErrMsg) } return ticketResp.Ticket, nil}接口3 // post 处理微信消息接口 微信扫码后,服务器被微信调用的接口// 微信消息结构体 type WxMessage struct { XMLName xml.Name `xml:"xml"` ToUserName string `xml:"ToUserName"` FromUserName string `xml:"FromUserName"` //卧槽这个就是openid CreateTime int64 `xml:"CreateTime"` MsgType string `xml:"MsgType"` Event string `xml:"Event"` //值有subscribe SCAN 暂时不知道啥意思,不过不影响逻辑 EventKey string `xml:"EventKey"`}3.1、func (ct *WeixinController) HandleWxMessage(ctx *gin.Context) { body, err := ioutil.ReadAll(ctx.Request.Body) if err != nil { ctx.String(400, "读取消息失败") return } var msg WxMessage if err := xml.Unmarshal(body, &msg); err != nil { ctx.String(400, "解析消息失败") return } returnmsg := "登录失败" // 处理关注事件 if msg.MsgType == "event" && msg.FromUserName != "" { // 检查是否包含场景值(二维码参数) if msg.EventKey != "" { loginCode := strings.TrimPrefix(msg.EventKey, "qrscene_") openid := msg.FromUserName /** * 1、查询三方库里是否有该用户, 如果有,直接保存登录状态 如果没有,创建账号,保存三方库 ,再保存登录状态 将loginCode作为登录标识符保存起来,便于,前端页面通过保存的loginCode 获取登录信息 */ //给扫码用户发送信息 ct.sendMessage(openid, "登录成功") } } ctx.String(200, "success")}3.2、// 向用户推送消息func (ct *WeixinController) sendMessage(openID, content string) error { // 获取access_token accessToken, err := ct.getAccessToken() if err != nil { return err } message := TextMessage{ ToUser: openID, MsgType: "text", } message.Text.Content = content jsonData, err := json.Marshal(message) if err != nil { return err } url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s", accessToken) resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData)) if err != nil { return err } defer resp.Body.Close() return nil}3.3、// 获取访问令牌func (ct *WeixinController) getAccessToken() (string, error) { appID := "微信公众号appid" appSecret := "微信公众号app_secret" url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appID, appSecret) resp, err := http.Get(url) if err != nil { return "", err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } var tokenResp AccessTokenResponse if err := json.Unmarshal(body, &tokenResp); err != nil { return "", err } if tokenResp.ErrCode != 0 { return "", fmt.Errorf("获取access_token失败:%s", tokenResp.ErrMsg) } return tokenResp.AccessToken, nil}


04_go-redis、session、cookie

一、redisgo get -u github.com/go-redis/redisvar redisdb *redis.Clientredisdb = redis.New(&redis.Options{ Addr:"127.0.0.1:6379", Password:"", DB:0,})redisdb.Set("test:name","value",time.Minute * 10) 十分钟失效 过期时间设置为0 是永不过期val,err:=redisdb.Get("key").Result()println(val) 二、sessiongo get github.com/gin-contrib/sessionsimport "github.com/gin-contrib/sessions"2.1、基于redis使用在main.go 中import( "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/redis")engine:=gin.Default()strore,_:=redis.NewStore(10,"tpc","localhost:6379","",[]byte("secret"))engine.Use(sessions.Sessions("mysession",store))engine.GET("/path",func(context *gin.Context){ session:=sessions.Default(context) //保存 num:=16 session.Set("count",num) session.Save() //读取 num=session.Get("count")})json.Marshal(member) //将 member 对象序列化session.Set("user_id",json.Marshal(member))反序列化var member Membersess:=session.Get("user_id")json.Unmarshal(sess.([]byte),&member)三、上传图片file,err:=context.FormFile("file")filename:="./uploadPath/"+strcov.Format(time.Now().Unix(),10)+file.Filenameerr:=context.SaveUploadFile(file,filename)四、cookie //设置cookiecontext.SetCookie("cookie_key","val",10*60,"localhost",true,true)获取cookiecookie,err:=context.Request.Cookie("cookie_key")const CookieName="cookie_user"const CookieTiimeLen=10*60func CookieAuth(context *gin.Context) (*http.Cookie,error){ cookie,err:=context.Request.Cookie(CookieName) if err==nil{ context.SetCookie(cookie.Name,cookie.Value,cookie.MaxAge,cookie.Path,cookie.Domain,cookie.Secure,cookie.HttpOnly) return cookie,nil }else{ return nil,err }}

微信支付

1、注意事项1.1、jsapi 支付时加载的是"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"而不是"github.com/wechatpay-apiv3/wechatpay-go/services/partnerpayments/jsapi"1.2、支付回调问题在 ParseNotifyRequest 之前不可使用 Request.Body原文链接wechatpay-go/FAQ.md at v0.2.20 · wechatpay-apiv3/wechatpay-go (github.com)2、JSAPI 接口3、支付回调func (ct *OrderController) WxPayBack(ctx *gin.Context) { dir, err := os.Getwd() if err == nil { fmt.Println("当前目录:", dir) } mchID := "商户号" mchCertificateSerialNumber := "API证书序列号" mchAPIV3Key := "APIV3密钥" // 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 mchPrivateKey, mchPrivateKeyErr := utils.LoadPrivateKeyWithPath(dir + "/filepath/apiclient_key.pem") if mchPrivateKeyErr != nil { println( mchPrivateKeyErr.Error()) return } // 1. 使用 `RegisterDownloaderWithPrivateKey` 注册下载器 errA := downloader.MgrInstance().RegisterDownloaderWithPrivateKey(ctx, mchPrivateKey, mchCertificateSerialNumber, mchID, mchAPIV3Key) if errA != nil { println( errA.Error()) return } // 2. 获取商户号对应的微信支付平台证书访问器 certificateVisitor := downloader.MgrInstance().GetCertificateVisitor(mchID) // 3. 使用证书访问器初始化 `notify.Handler` handler := notify.NewNotifyHandler(mchAPIV3Key, verifiers.NewSHA256WithRSAVerifier(certificateVisitor)) transaction := new(payments.Transaction) request := ctx.Request _, handlErr := handler.ParseNotifyRequest(ctx, request, &transaction) // 如果验签未通过,或者解密失败 if handlErr != nil { fmt.Println( err) return } // 处理通知内容 /** transaction 结构 Transaction{ Amount:TransactionAmount{ Currency:CNY, PayerCurrency:CNY, PayerTotal:1, //单位是分 Total:1 }, Appid:wxb*****e399, Attach:, BankType:OTHERS, Mchid:商户号, OutTradeNo:2025A*****F012, Payer:TransactionPayer{ Openid:ohkRO********aSHxc }, PromotionDetail:[], SuccessTime:2025-02-16T15:25:58+08:00, TradeState:SUCCESS, TradeStateDesc:支付成功, TradeType:JSAPI, TransactionId:4200**********5263 } */ if *transaction.TradeState == "SUCCESS" { }}

08_图片上传

1、获取图片长宽 import( "image" _ "image/gif" _ "image/jpeg" _ "image/png" ) src,err:=file.Open() img,ext,err:=image.DecodeConfig(src) fmt.Println("width:",img.Width) fmt.Println("height",img.Height) fmt.Println("后缀",ext) //不包含. 2、获取图片类型 安装 go get github.com/shamsher31/goimgtype // 图片路径 var file_name string = `./test.png` // 读取图片 old_file, err1 := os.Open(file_name) if err1 != nil { panic(err) } defer old_file.Close() // 获取图片的类型 datatype, err2 := imgtype.Get(file_name) if err2 != nil { println(`不是图片文件`) } else { // 根据文件类型执行响应的操作 switch datatype { case `image/jpeg`: println(`这是JPG文件`) case `image/png`: println(`这是PNG文件`) } } 七牛云上传 type MyPutRet struct { Key string Hash string Fsize int Bucket string Name string } func upQiniu(file *multipart.FileHeader, ctx *gin.Context) { putPolicy := storage.PutPolicy{ Scope: Conf.Qiniu.Bucket, } src, err := file.Open() if err != nil { return } img, ext, err := image.DecodeConfig(src) if err != nil { return } name1 := time.Now().Format("20060102150405") name2 := rand.Intn(1000) name := name1 + strconv.Itoa(name2) + "." + ext fmt.Println("name:", "upload/"+name) fmt.Printf("===a=w= %d= %d", img.Width, img.Height) src.Close() src, err = file.Open() if err != nil { return } defer src.Close() mac := qbox.NewMac(Conf.Qiniu.AccessKey, Conf.Qiniu.SecretKey) upToken := putPolicy.UploadToken(mac) fmt.Println("result===b") cfg := storage.Config{} formUploader := storage.NewFormUploader(&cfg) ret := MyPutRet{} putExtra := storage.PutExtra{} err = formUploader.Put(ctx, &ret, upToken, "upload/"+name, src, file.Size, &putExtra) if err != nil { fmt.Println(err) return } fmt.Println("ret.Key:", ret.Key) }

基础笔记

linux下安装go 先安装epel:yum install epel-release 然后再安装golang:yum install golang 或者 rpm --import https://mirror.go-repo.io/centos/RPM-GPG-KEY-GO-REPO curl -s https://mirror.go-repo.io/centos/go-repo.repo | tee /etc/yum.repos.d/go-repo.repo yum install golang 后台启动项目 go build main.go 生成 main 文件 nohup ./main & 后台启动命令 ps aux |grep main 找到进程 kill -9 进程id 一、array 数组 slice 是个概念,不是函数 二、map 对象 2.1、初始化时需用make arr:=make(map[int]string) 2.2、批量赋值时用不用make arr:=map[string]string{"name":"jim","age":"15"} 2.3、复合map arr:make(map[string]map[int]string) arr['name'] = make(map[int]string) arr['name'][1] = "hello" 三、function 关键字func 不支持嵌套、重载和默认参数 四、struct type person struct{ name string age int } func main(){ a:=person{name:"jim",age:18} } 五、method 任何类型数据都可以绑定方法 例1: type person struct{ name stype } func (man person) act{ fmt.Println("hello") } func main(){ man:=person{} main.act() // 输出 hello } 例2: type num int func (n *num) act{ fmt.Println("hello") } func main(){ var n num n.act() //输出hello } 六、接口interface import "reflect" type User struct{ Id int Name string Age int } func (u User) Hello(){ fmt.Println("hello") } //不能引用传参 func Info(o interface{}){ t:=reflect.TypeOf(o) if k:=t.Kind();k!=reflect.Struct { return } fmt.Println("Type:",t.Name()) fmt.Println(t.NumField()) v:=reflect.ValueOf(o) // 获取成员信息 for i:=0;i<t.NumField();i++{ f:=t.Field(i) val:=v.Field(i).Interface() fmt.Printf("%6s: %v = %v\n",f.Name,f.Type,val) } // 获取方法信息 for i:=0;i<t.NumMethod(); i++{ m:=t.Method(i) fmt.Printf("%6s: %v\n",m.Name,m.Type) } } func main(){ u:=User{1,"jim",12} Info(u) } 七、反射reflection 八、并发concurrency func main(){ c:=make(chan bool) //无缓存是阻塞的,只定义或有缓存不阻塞 <-c 使其无缓存,进行阻塞 go func(){ fmt.Println("go go go!!!") c <- true } <- c } 8.1、例1 import ( "fmt" "runtime" ) func main(){ runtime.GOMAXPROCS(runtime.NumCPU()) //分配最大核数cpu c :=make(chan bool,10) for i:=0;i<10;i++{ go Go(c) } for i:=0;i<10;i++{ <-c } } func Go(c chan bool){ fmt.Println("go go go!!!") c<- true } 8.2、例2 import ( "fmt" "runtime" "sync" ) func main(){ runtime.GOMAXPROCS(runtime.NumCPU()) //分配最大核数cpu wg:=sync.WaitGroup{} wg.Add(10) for i:=0;i<10;i++{ go Go(&wg) } wg.Wait() } func Go(wg *sync.WaitGroup){ fmt.Println("go go go!!!") wg.Done() } 随机产生数字 code := fmt.Sprintf( "%06v", rand.New(rand.NewSource( time.Now().UnixNano() )).Int3ln(1000000) )




01_gin安装,参数

一、安装 go mod init ginchat go get -u github.com/gin-gonic/gin 如果报错输入以下命令解决 go env -w GOPROXY="https://goproxy.io" 或者 go env -w GOPROXY="https://goproxy.cn" go env -w GO111MODULE="on" 还报错就 go env -w GOSUMDB=off 二、基础服务 package main import ( "github.com/gin-gonic/gin" "log" "fmt" ) func main(){ engine:=gin.Default() engine.GET("/hello",func(context *gin.Context){ fmt.Print("hello world:",context.FullPath()) // 后端打印 name:=context.DefaultQuery("name","hello") //获取get请求参数name 如果没有则默认值为 hello context.Writer.Write([]byte("hello,gin\n")) // 前端输出 }) engine.Handle("POST","/login",func(context *gin.Context){ username:=context.PostForm("username") //获取post 参数 username username,exist:=context.GetPostForm("username") // 获取post 参数username 如果存在则exist为ture 否则为false }) // 路径中的变量加冒号 engine.DELETE("/user/:id",func(context *gin.Context){ userId:=context.Param("id") //获取路径中的变量值 }) if err:=engine.Run();err!=nil { log.Fatal(err.Error()) } } 三、请求数据绑定 type Student struct{ Name string `form:"name"` //绑定参数中的name Classes string `form:"classes"` //绑定参数中的classes } 1、绑定get请求数据 var student Student err:= context.ShouldBindQuery(&student) if err != nil { log.Fatal(err.Error()) return } 2、绑定post form 表单请求数据 err:= context.ShouldBind(&student) 可接收 ajax 的object{key:value} 或 form.serialize(key=val&key=val) 数据 3、绑定post json数据 接收ajax 的object err:=context.BindJSON(&student) 4、解析body type Person struct { Name string `json:"name"` Code string `json:"code"` } json.NewDecoder(context.Request.Body).Decode(&person ) ajax 传 data:JSON.stringify(objct) 5、接收file file,err:=context.FormFile("file") 四、输出 4.1、context.Writer.Write([]byte("hello")) // 4.2、context.Writer.WriteString("hello") 4.3、context.JSON(200,map[string]interface{}{ "code":1, "message":"请求成功", "data":name, }) 4.4、 type Response struct{ Code int Message string Data interface{} } resp:=Response{Code:1,Message:"ok",Data:name} context.JSON(200,&resp) 4.5、加载html engine.LoadHTMLGlob("./html/*") //加载html资源引擎 enginx.Static("/img","./img") //加载静态资源映射 context.HTML(http.StatusOK,"index.html",nil) context.HTML(http.StatusOK,"index.html",gin.H{ "resp":resp, }) html模板引擎获取数据 {{.resp.Code}} 五、路由组 userGroup :=engine.Group("/user") 六、渲染带html 标签的字符串 app:=gin.Default() app.SetFuncMap(template.FuncMap{ "safe": func(str string) template.HTML { return template.HTML(str) }, "trimHtml": func(src string) string { //将HTML标签全转换成小写 re, _ := regexp.Compile("\\<[\\S\\s]+?\\>") src = re.ReplaceAllStringFunc(src, strings.ToLower) //去除STYLE re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>") src = re.ReplaceAllString(src, "") //去除SCRIPT re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>") src = re.ReplaceAllString(src, "") //去除所有尖括号内的HTML代码,并换成换行符 re, _ = regexp.Compile("\\<[\\S\\s]+?\\>") src = re.ReplaceAllString(src, "\n") //去除连续的换行符 re, _ = regexp.Compile("\\s{2,}") src = re.ReplaceAllString(src, "\n") return strings.TrimSpace(src) }, }) //模板里 {{.content|safe}} //解析html标签 {{.content|trimHtml}} // 去除html标签 userGroup.GET("/login",func(context *gin.Context){})

02_gin跨域,mysql

六、mysql 安装驱动 go get "github.com/go-sql-driver/mysql" import _ "github.com/go-sql-driver/mysql" import ( _ "github.com/go-sql-driver/mysql" "database/sql" ) connstr:="root:password@tcp(127.0.0.1:3306)databasename" db,err :=sql.Open("mysql",connStr) if err != nil { log.Fatal(err.Error()) return } 创建表 _,err = db.Exec("create table person("+ "id int auto_increment primary key," + "name varchar(12) not null,"+ "age int default 1"+ )") 插入 _,err = db.Exec("insert into person (name,age) values (?,?);","username",18) 查询 type Person struct{ Id int Name string Age int } rows,err:= db.Query("slelect * from person limit 10") scan: if rows.Next(){ person:= new(Person) rows.Scan(&person.Id,&person.Nane,&person.Age) goto scan } 七、定义及调用配置文件 7.1、定义配置文件 config/app.json { "app_name":"cloudrestaurant", "app_mode":"debug", "app_host":"localhost", "app_port":"8080" } 7.2、定义解析配置文件的工具 tools/Config.go package tool import ("os" "bufio" "encoding/json") type Config struct{ AppName string `json:"app_name"` AppMode string `json:"app_name"` AppHost string `json:"app_name"` AppPort string `json:"app_name"` } var _cfg *Config=nil func ParseConfig(path string) (*Config,error){ file,err := os.Open(path) if err !=nil { panic(err) } defer file.Close() reader:=bufio.NewReader(file) decoder:=json.NewDecode(reader) if err:=decoder.Decode(&_cfg);err!=nil{ return nil,err } return _cfg,nil } 八、控制器路由 8.1、controller/HelloController.go package controller import "github.com/gin-goic/gin" type HelloController struct { } func (hello *HelloController) Router(engine *gin.Engine){ engine.GET("hello",hello.Hello) } func (hello *HelloController) Hello(context *gin.Context){ } 8.2、main.go func registerRouter(router *gin.Engine){ new(controller.HelloController).Router(router) } app:=gin.Defult() register() 九、跨域 main.go func Cors() gin.HandlerFunc { return func(context *gin.Context) { method := context.Request.Method context.Header("Access-Control-Allow-Origin", "*") context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToke,X-CSRF-Token,Authorization,Token,x-token") context.Header("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PATCH,PUT") context.Header("Access-Control-Expose-Headers", "Content-Lenth,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Content-Type") context.Header("Access-Control-Allow-Credentials", "true") if method == "OPTIONS" { context.AbortWithStatus(http.StatusNoContent) //context.JSON(http.StatusOK, "Options Request!") } context.Next() } } 使用 app := gin.Default() app.Use(Cors())

03_xorm

一、安装 go get github.com/go-xorm/xorm 使用示例 // 结构体名称对应数据库表名 type Smscode struct { Id int `xorm:"pk autoincr" json:"id"` Code string `xorm:"varchar(255)" json:"code"` Phone string `xorm:"varchar(255)" json:"phone"` CreateTime int `xorm:"int" json:"create_time"` } import ( _ "github.com/go-sql-driver/mysql" "github.com/go-xorm/xorm" ) conn := "root:password@tcp(127.0.0.1:port)/database?charset=utf8mb4" eg, err := xorm.NewEngine("mysql", conn) if err != nil { fmt.Println("链接失败") } fmt.Println("链接成功。。。") eg.ShowSQL(true) //映射结构体,好像没什么卵用 err = eg.Sync2(new(Smscode)) if err != nil { fmt.Println("映射失败") } smsCode := Smscode{Code: "123456", Phone: "15700000000", CreateTime: 12345678910} fmt.Println(smsCode) result, err := eg.InsertOne(smsCode) if err != nil { fmt.Println("插入失败") } fmt.Println(result) //事物 eg, err := xorm.NewEngine("mysql", conn) defer eg.Close() sess:=eg.NewSession() err:=sess.Begin() sess执行sql语句 sess.Rollback() sess.Commit() 条件查询 var sms model.SmsCode // eg,err:= xorm.NewEngine("mysql",[connectString]) _,err:=eg.Where("phone= ? and code = ?",phone,code).Get(&sms) 1.1、service 封装 tool/OrmEngine.go import ( "github.com/go-xorm/xorm" _ "github.com/go-sql-driver/mysql" ) type Orm struct{ *xorm.Engine } var DbEngine *Orm func OrmEngine(cfg *Config) (*Orm,error){ database : = cfg.Database conn:=database.User+":"+database.Password + "@tcp("+database.Host+":"+database.Port+")/"+database.Database+"?charset=utf8" engine,err :=xorm.NewEgine("mysql",conn) if err !=nil { return nil,err } engine.ShowSQL(true) err :=engine.Sync2(new(model.SmsCode)) orm :=new(Orm) orm.Engine =engine DbEngine = orm return orm,nil } 1.2、model调用 model/SmsCode.go type SmsCode struct { Id int64 `xorm:"pk autoincr" json:"id"` Phone string `xorm:"varchar(11)" json:"phone"` CreateTime int64 `xorm:"bigint" json:"create_time"` } 1.3、dao/MemberDao.go type MemberDao struct{ *tool.Orm } func (md *MemberDao) InsertCode(sms model.SmsCode) int64{ result,err :=md.InsertOne(&sms) //返回的是插入的id return result } 1.4、service/MemberService.go 当前时间 time.Now().Unix() smsCode:=model.SmsCode(Phone:phone,Code:code,CreateTime:time.Now().Unix()) memberDao:=dao.MemberDao{} res:=memberDao.InsertCode(smsCode)