创建一个函数,使用Golang和MGO返回一个Mongo集合。

huangapple go评论73阅读模式
英文:

Create a function which returns a mongo collection with Golang and MGO

问题

我是你的中文翻译助手,以下是翻译好的内容:

我对GOLANG还不熟悉,我想要减少我的GO API中处理程序的复杂性。我之前是使用Node.js的。

目前,一个路由处理程序的代码如下:

func getCards(c web.C, w http.ResponseWriter, r *http.Request) {

    session := *MongoConnection().CreateSession()
    defer session.Close()

    collection := session.DB(db).C(cardsCollection)

    result := []Card{}

    err := collection.Find(bson.M{}).All(&result)
    if err != nil {
        panic(err)
    }

    w.Header().Set("Content-Type", "application/json")
    encoder := json.NewEncoder(w)
    encoder.Encode(result)
}

我想要做的是在不执行以下部分的情况下返回一个集合:

session := *MongoConnection().CreateSession()
defer session.Close()

collection := session.DB(db).C(cardsCollection)

而是想要像这样做:

collection := Card.Collection()

并且它会创建会话等等,这种方式可行吗?

英文:

I'm new to GOLANG - I would like to reduce the complexity of the handlers in my GO API. I'm coming from a Node.js background!

At the moment a route handler looks like this:

func getCards(c web.C, w http.ResponseWriter, r *http.Request) {

    session := *MongoConnection().CreateSession()
    defer session.Close()

    collection := session.DB(db).C(cardsCollection)

    result := []Card{}

    err := collection.Find(bson.M{}).All(&result)
    if err != nil {
	    panic(err)
    }

    w.Header().Set("Content-Type", "application/json")
    encoder := json.NewEncoder(w)
    encoder.Encode(result)
}

What I would like to do is return a collection for use without having to do this part:

session := *MongoConnection().CreateSession()
defer session.Close()

collection := session.DB(db).C(cardsCollection)

Instead I would like to do something like

collection := Card.Collection()

And have it create the session etc, Is this possible?

答案1

得分: 1

为什么你的main函数中没有创建会话,并将其传递给需要它的包呢?这显然缺少了很多东西,但是一般的想法是这样的:

main函数中:

package main
// 导入包
func main() {
    session := *MongoConnection().CreateSession()
    defer session.Close()
    Card.SetSession(session)
    // 其他操作
    log.Fatal(http.ListenAndServe(":80", nil))
}

然后在Card包中:

package Card

var session *mgo.Session

func SetSession(s *mgo.Session) {
    session = s
}

func (c *Card) Collection() *mgo.Collection {
    return session.DB(db).C(cardsCollection)
}

这样,你可以在main函数中创建会话,并将其传递给Card包中的其他函数使用。

英文:

Why don't you have the session created in your main function, and pass it to the packages that need it. This is obviously missing a ton of stuff but the general idea would be

package main
//imports
func main() {
    session := *MongoConnection().CreateSession()
    defer session.Close()
    Card.SetSession(session)
    //other stuff
    log.Fatal(http.ListenAndServe(":80", nil))
}

Then in Card

package Card

var session *mgo.Session

func SetSession(s *mgo.Session) {
    session = s
}

func (c *Card) Collection() *mgo.Collection {
    return session.DB(db).C(cardsCollection)
}

答案2

得分: 0

你所描述的是工厂模式。但是有一些需要处理的注意事项。
defer语句的作用范围是它被调用的局部范围。所以如果你将defer放在一个工厂方法中,当它被返回时,会关闭会话。

简单地定义一个会话并在各个地方重复使用它,与使用单个SQL数据库连接而不是连接池几乎没有区别-它的扩展性非常差。

以下是我倾向于做的事情:我将我的集合作为全局变量,并在方法开始时执行以下操作:

// 创建一个函数局部的会话
myCollection := globalCollection.With(globalCollection.Database.Session.Copy())
// 在作用域退出时关闭会话
defer myCollection.Database.Session.Close()

当然,你也可以将第一行代码提取到一个工厂中,但这并不会真正简化代码或使其更易读。

英文:

What you are describing is a factory pattern. But there are caveats to deal with.
Defer is local to scope it is called. So in case you would put the defer into a factory method, the session would be closed basically when it is returned.

Simply defining just one session und reuse it all over the place is pretty much the same as using a single SQL database connection and not a pool - it scales horribly.

Here is what I tend to do: I have my collections as global, and do the following at the beginning of my method

<!-- language: lang-go -->

// Create a func-local session
myCollection := globalCollection.With( globalCollection.Database.Session.Copy() )
// Close it on exiting the scope
defer myCollection.Database.Session.Close()

Of course, you could externalize the first line into a factory, but that would not really declutter the code or make it more readable.

huangapple
  • 本文由 发表于 2015年10月21日 00:15:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/33241679.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定