英文:
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 (
"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.a new db connection on every request
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()
}
......
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论