如何从处理程序中调用mongoDB的CRUD方法?

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

How do I call mongoDB CRUD method from handler?

问题

我写了一个简单的MongoDB包,其中包含一些CRUD方法:

package backend

import "labix.org/v2/mgo"

type MongoDBConn struct {
    session *mgo.Session
}

type ToDo struct {
    Title       string
    Description string
}

func NewMongoDBConn() *MongoDBConn {
    return &MongoDBConn{}
}

func (m *MongoDBConn) Connect(url string) *mgo.Session {
    session, err := mgo.Dial(url)
    if err != nil {
        panic(err)
    }
    m.session = session
    return m.session
}

func (m *MongoDBConn) Stop() {
    m.session.Close()
}

func (m *MongoDBConn) AddToDo(title, description string) (err error) {
    c := m.session.DB("test").C("people")
    err = c.Insert(&ToDo{title, description})
    if err != nil {
        panic(err)
    }
    return nil
}

我有一个server.go文件,在其中创建了一个HTTP服务器,并为不同的URL设置了处理程序。我想能够连接到MongoDB并在特定的处理程序中调用AddToDo方法。我可以从服务器的main方法中连接到数据库:

import (
    "./backend"
    //其他引入的代码
)

func AddHandler(writer http.ResponseWriter, request *http.Request) {
    log.Printf("serving %v %v", request.Method, request.URL.Path[1:])
    if request.Method != "POST" {
        serve404(writer)
        return
    }
    title := request.FormValue("title")
    description := request.FormValue("description")
    fmt.Fprintf(writer, " title description %v %v", title, description)
    //我无法从这里调用mongoConn.AddToDo(title, description)
}    

func main() {
    //连接到MongoDB
    mongoConn := backend.NewMongoDBConn()
    _ = mongoConn.Connect("localhost")
    defer mongoConn.Stop()
}

但是我不确定如何从处理程序中调用mongoConn.AddToDo(title, description string)方法。我应该创建一个全局的数据库连接变量吗?

英文:

I've written a simple MongoDB package with some CRUD methods:

package backend

import "labix.org/v2/mgo"

type MongoDBConn struct {
	session *mgo.Session
}

type ToDo struct {
	Title       string
	Description string
}

func NewMongoDBConn() *MongoDBConn {
	return &MongoDBConn{}
}

func (m *MongoDBConn) Connect(url string) *mgo.Session {
	session, err := mgo.Dial(url)
	if err != nil {
		panic(err)
	}
	m.session = session
	return m.session
}

func (m *MongoDBConn) Stop() {
	m.session.Close()
}

func (m *MongoDBConn) AddToDo(title, description string) (err error) {
	c := m.session.DB("test").C("people")
	err = c.Insert(&ToDo{title, description})
	if err != nil {
		panic(err)
	}
	return nil
}

I have a server.go where I create a Http Server and have handlers for the different URLs. I'd like to be able to connect to MongoDB and call the AddToDo method within a specific handler. I can connect to the DB from the main method of my server:

import (
	"./backend"
       //other boilerplate imports
)

func AddHandler(writer http.ResponseWriter, request *http.Request) {
	log.Printf("serving %v %v", request.Method, request.URL.Path[1:])
	if request.Method != "POST" {
		serve404(writer)
		return
	}
	title := request.FormValue("title")
	description := request.FormValue("description")
	fmt.Fprintf(writer, " title description %v %v", title, description)
//I can't call mongoConn.AddToDo(title, description) from here

}    
func main() {
    	//connect to mongoDB
    	mongoConn := backend.NewMongoDBConn()
    	_ = mongoConn.Connect("localhost")
    	defer mongoConn.Stop()
    }

But I'm not sure how to call mongoConn.AddToDo(title, description string) method from the handler. Should I create a global db connection variable?

答案1

得分: 3

是的,全局会话是处理这个问题的一种简单方法。然后,在每个处理程序的顶部,您可以执行类似以下的操作:

func handler(...) {
    session := globalSession.Copy()
    defer session.Close()
}

这样每个处理程序都会获得自己的会话来处理。

请注意,复制和关闭会话是廉价的操作,它们在内部使用连接池而不是为每个创建的会话建立新连接。

英文:

Yes, a global session is an easy way to handle that. Then, at the top of every handler, you can do something along the lines of:

func handler(...) {
    session := globalSession.Copy()
    defer session.Close()
}

so that each handler gets its own session to work with.

Note that copying and closing sessions are cheap operations, that internally will work against a pool of connections rather than establishing new connections for every session created.

答案2

得分: 2

两种简单的方法:

1.全局数据库会话

package main

import (
    "net/http"
    "log"
    "fmt"
    "./backend"
)

var mongoConn *backend.MongoDBConn

func AddHandler(w http.ResponseWriter, r *http.Request) {
    log.Printf("serving %v %v", r.Method, r.URL.Path[1:])
    if r.Method != "POST" {
        fmt.Fprintln(w, "Not POST Method ")
        return
    }
    title := r.FormValue("title")
    description := r.FormValue("description")

    fmt.Fprintf(w, " title description %v %v", title, description)
    //I can't call mongoConn.AddToDo(title, description) from here
    mongoConn.AddToDo(title, description)
}    

const AddForm = `
<html><body>
<form method="POST" action="/add">
Name: <input type="text" name="title">
Age: <input type="text" name="description">
<input type="submit" value="Add">
</form>
</body></html>
`
func Index(w http.ResponseWriter, r *http.Request) {
   fmt.Fprintln(w, AddForm)
}

func main() {
        //connect to mongoDB

       mongoConn = backend.NewMongoDBConn()
        _ = mongoConn.Connect("localhost")
        defer mongoConn.Stop()

        http.HandleFunc("/", Index)
        http.HandleFunc("/add", AddHandler)

        log.Println("Start Server:")
        err := http.ListenAndServe(":8080", nil)

        if err != nil {
            log.Fatal("ListenAndServe:", err)
        }
}

2.每个请求都创建一个新的数据库连接

import (
    "./backend"
       //other boilerplate imports
)

func AddHandler(writer http.ResponseWriter, request *http.Request) {
    log.Printf("serving %v %v", request.Method, request.URL.Path[1:])
    if request.Method != "POST" {
        serve404(writer)
        return
    }
    title := request.FormValue("title")
    description := request.FormValue("description")
    fmt.Fprintf(writer, " title description %v %v", title, description)
    //................
    mongoConn := backend.NewMongoDBConn()
    _ = mongoConn.Connect("localhost")
    mongoConn.AddToDo(title, description)
    //....................
    mongoConn.Stop()

} 

......

更好的解决方案:

您可以创建一个数据库会话池,在处理请求之前选择一个并将其放入该请求的上下文中。然后在请求完成后将连接推回到池中。

如果池为空,则创建一个新的连接。如果池已满,则关闭连接。

更多信息,请点击这里

英文:

Two simple method:

1.global database session

package main
import (
&quot;net/http&quot;
&quot;log&quot;
&quot;fmt&quot;
&quot;./backend&quot;
)
var mongoConn * backend.MongoDBConn
func AddHandler(w http.ResponseWriter, r *http.Request) {
log.Printf(&quot;serving %v %v&quot;, r.Method, r.URL.Path[1:])
if r.Method != &quot;POST&quot; {
fmt.Fprintln(w, &quot;Not POST Method &quot;)
return
}
title := r.FormValue(&quot;title&quot;)
description := r.FormValue(&quot;description&quot;)
fmt.Fprintf(w, &quot; title description %v %v&quot;, title, description)
//I can&#39;t call mongoConn.AddToDo(title, description) from here
mongoConn.AddToDo(title, description)
}    
const AddForm = `
&lt;html&gt;&lt;body&gt;
&lt;form method=&quot;POST&quot; action=&quot;/add&quot;&gt;
Name: &lt;input type=&quot;text&quot; name=&quot;title&quot;&gt;
Age: &lt;input type=&quot;text&quot; name=&quot;description&quot;&gt;
&lt;input type=&quot;submit&quot; value=&quot;Add&quot;&gt;
&lt;/form&gt;
&lt;/body&gt;&lt;/html&gt;
`
func Index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, AddForm)
}
func main() {
//connect to mongoDB
mongoConn = backend.NewMongoDBConn()
_ = mongoConn.Connect(&quot;localhost&quot;)
defer mongoConn.Stop()
http.HandleFunc(&quot;/&quot;, Index)
http.HandleFunc(&quot;/add&quot;, AddHandler)
log.Println(&quot;Start Server:&quot;)
err := http.ListenAndServe(&quot;:8080&quot;, nil)
if err != nil {
log.Fatal(&quot;ListenAndServe:&quot;, err)
}
}

2.a new db connection on every request

import (
&quot;./backend&quot;
//other boilerplate imports
)
func AddHandler(writer http.ResponseWriter, request *http.Request) {
log.Printf(&quot;serving %v %v&quot;, request.Method, request.URL.Path[1:])
if request.Method != &quot;POST&quot; {
serve404(writer)
return
}
title := request.FormValue(&quot;title&quot;)
description := request.FormValue(&quot;description&quot;)
fmt.Fprintf(writer, &quot; title description %v %v&quot;, title, description)
//................
mongoConn := backend.NewMongoDBConn()
_ = mongoConn.Connect(&quot;localhost&quot;)
mongoConn.AddToDo(title, description)
//....................
mongoConn.Stop()
} 
......

a better solution:

> You could create a pool of db sessions, then before processing the
> request you pick one and put in the context of that request. Then
> after the request is done you push the connection back to the pool.
>
> If the pool is empty you create a new connection If the pool is full
> you close the connection

For more information, click here.

huangapple
  • 本文由 发表于 2012年12月24日 16:16:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/14018864.html
匿名

发表评论

匿名网友

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

确定