登录
首页 >  Golang >  Go问答

将标题重新写为:在 MongoDB 中插入处理程序

来源:stackoverflow

时间:2024-03-03 14:27:25 103浏览 收藏

目前golang学习网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《将标题重新写为:在 MongoDB 中插入处理程序》,也希望能帮助到大家,如果阅读完后真的对你学习Golang有帮助,欢迎动动手指,评论留言并分享~

问题内容

我有代码,当我尝试此调用控制台时,请写入 undefined: insertcontractdata。我尝试更改此代码,但在 无效内存地址或零指针取消引用 上出现错误,我无法理解如何正确执行此操作。

我认为我写的结构不对 我还不能编译两天,请告诉我我不这样做。

我使用官方的mongo-go驱动程序来连接到该语言的骄傲,因此我无法作为官方文档更准确地连接到plaza本身。如果都是我的,原来是有联系的。单独地,连接每个集合,它不起作用这个代码通常应该以某种方式开始工作,但是工作没有发生,或者更确切地说它工作不正确,对结构发誓,所以它更对一个方法发誓未命名 这是如何修复它,我不知道,但我希望有一些解决方案来解决这个问题,在此感谢您的帮助。

package main

import (
    "context"
    "encoding/json"
    "log"
    "net/http"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type Data struct {
    Number    string `json:"number"`
    Driver    string `json:"driver"`
    Auto      string `json:"auto"`
    Tariff    string `json:"tariff"`
    Begindate string `json:"begindate"`
    Enddate   string `json:"enddate"`
    Continues bool   `json:"continues"`
    MoreInfo  string `json:"moreInfo"`
    Status    string `json:"status"`
}

type MyClient struct {
    mc *mongo.Client
    db *mongo.Database
}

func setupResponse(w http.ResponseWriter, req *http.Request) {
    (w).Header().Set("Access-Control-Allow-Origin", "*")
    (w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
    (w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}

func NewMyClient(url, db string) (mc *MyClient, err error) {
    defer func() {
        if err != nil {
            mc = nil
        }
    }()
    mc = &MyClient{}
    if mc.mc, err = mongo.NewClient(options.Client().ApplyURI(url)); err != nil {
        return
    }
    ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
    err = mc.mc.Connect(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer mc.mc.Disconnect(ctx)
    mc.db = mc.mc.Database(db)
    return
}

func (mc *MyClient) insertContractData(w http.ResponseWriter, r *http.Request) {
    setupResponse(w, r)
    var err error
    var data Data
    err = json.NewDecoder(r.Body).Decode(&data)
    if err != nil {
        return
    }

    podcastsCollection := mc.db.Collection("test")
    ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
    defer mc.mc.Disconnect(ctx)
    _, err = podcastsCollection.InsertOne(ctx, bson.D{
        {"number", data.Number},
        {"driver", data.Driver},
        {"auto", data.Auto},
        {"tariff", data.Tariff},
        {"begindate", data.Begindate},
        {"enddate", data.Enddate},
        {"continues", data.Continues},
        {"moreInfo", data.MoreInfo},
        {"status", data.Status},
    })
    if err != nil {
        log.Fatal(err)
    }
}

func main() {
    var mc MyClient
    http.HandleFunc("/insertContractData", insertContractData)
    //http.HandleFunc("/selectContractData", selectContractData)
    http.ListenAndServe(":8081", nil)
}

解决方案


您的示例存在一些问题。

首先,context.WithTimeout() 返回一个 context.Context 和一个您需要调用的 cancel 函数,最好使用 defer 以确保释放分配的资源。

接下来,newmyclient() 负责连接到 mongodb 服务器,但在您的代码中您永远不会调用它。您应该在 main() 中调用它。

接下来,在 main() 中,insertcontractdata 标识符未定义。您很可能希望将 mc.insertcontractdata 方法注册为处理程序(顺便说一句,这是 method value)。

您永远不应该关闭 mongodb 连接,当然也不应该在处理程序结束时关闭,也不应该在 newmyclient() 函数中关闭。 defer mc.mc.disconnect(ctx) 行不仅不需要,还会使您的应用程序无法正常工作。 mongo.Client 的设计寿命很长。它有一个内部连接池,并且应该只创建一次,并从多个 goroutine 中重用。它只能在应用程序关闭时关闭。

所以你的 main() 函数应该如下所示:

func main() {
    mc, err := newmyclient("mongodb://localhost:27017", "somedb")
    if err != nil {
        panic(err)
    }
    http.handlefunc("/insertcontractdata", mc.insertcontractdata)
    panic(http.listenandserve(":8081", nil))
}

newmyclient() 可能如下所示:

func newmyclient(url, db string) (mc *myclient, err error) {
    mc = &myclient{}
    if mc.mc, err = mongo.newclient(options.client().applyuri(url)); err != nil {
        return
    }
    ctx, cancel := context.withtimeout(context.background(), 10*time.second)
    defer cancel()
    err = mc.mc.connect(ctx)
    if err != nil {
        log.fatal(err)
    }
    mc.db = mc.mc.database(db)
    return
}

和处理程序:

func (mc *myclient) insertcontractdata(w http.responsewriter, r *http.request) {
    setupresponse(w, r)
    var err error
    var data data
    err = json.newdecoder(r.body).decode(&data)
    if err != nil {
        fmt.println(err)
        return
    }

    podcastscollection := mc.db.collection("test")
    ctx, cancel := context.withtimeout(context.background(), 10*time.second)
    defer cancel()
    _, err = podcastscollection.insertone(ctx, bson.d{
        {"number", data.number},
        {"driver", data.driver},
        {"auto", data.auto},
        {"tariff", data.tariff},
        {"begindate", data.begindate},
        {"enddate", data.enddate},
        {"continues", data.continues},
        {"moreinfo", data.moreinfo},
        {"status", data.status},
    })
    if err != nil {
        log.fatal(err)
    }
}

现在我们可以运行这个应用程序了。

我们可以使用以下 curl 命令对其进行测试:

curl -d '{"number":"11","driver":"dr1","status":"s1"}' -x post http://localhost:8081/insertcontractdata

如果我们连接到 mongodb 数据库,并执行 db.test.find(),我们将看到以下文档:

{ "_id" : ObjectId("5e123e6c1618bd4c80a2e13f"), "number" : "11", "driver" : "dr1", "auto" : "", "tariff" : "", "begindate" : "", "enddate" : "", "continues" : false, "moreInfo" : "", "status" : "s1" }

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>