如何从处理程序调用mongoDB CRUD方法?
我用一些CRUD方法编写了一个简单的MongoDB包:如何从处理程序调用mongoDB CRUD方法?,mongodb,go,Mongodb,Go,我用一些CRUD方法编写了一个简单的MongoDB包: package backend import "labix.org/v2/mgo" type MongoDBConn struct { session *mgo.Session } type ToDo struct { Title string Description string } func NewMongoDBConn() *MongoDBConn { return &Mon
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方法。我可以从服务器的主方法连接到数据库:
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()
}
但我不确定如何从处理程序调用mongoConn.AddToDo(title,description string)方法。我应该创建一个全局db连接变量吗?两个简单的方法:
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)
}
}
更好的解决方案:
您可以创建一个数据库会话池,然后在处理
请求您选择一个并放入该请求的上下文中。然后
请求完成后,将连接推回池
如果池为空,则在池已满时创建新连接
你关闭连接
有关详细信息,请单击。两种简单方法:
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)
}
}
更好的解决方案:
您可以创建一个数据库会话池,然后在处理
请求您选择一个并放入该请求的上下文中。然后
请求完成后,将连接推回池
如果池为空,则在池已满时创建新连接
你关闭连接
有关详细信息,请单击。是的,全局会话是处理此问题的简单方法。然后,在每个处理程序的顶部,您可以执行以下操作:
func handler(...) {
session := globalSession.Copy()
defer session.Close()
}
这样每个处理程序都有自己的会话来处理
请注意,复制和关闭会话是一种廉价的操作,它在内部将针对连接池工作,而不是为创建的每个会话建立新的连接。是的,全局会话是一种简单的处理方法。然后,在每个处理程序的顶部,您可以执行以下操作:
func handler(...) {
session := globalSession.Copy()
defer session.Close()
}
这样每个处理程序都有自己的会话来处理
请注意,复制和关闭会话是一种廉价的操作,它在内部将针对一个连接池工作,而不是为创建的每个会话建立新的连接。全局变量的第一个解决方案,我以前尝试过,但不起作用。我一直收到这个错误:http:panic serving[::1]:55642:运行时错误:无效的内存地址或零指针取消引用定义一个全局变量:
var mongoConn*benkend.MongoDBConn
,在主函数中连接mongodb:mongocon=backend.NewMongoDBConn()
。我已经更改了上面的代码,它是有效的。创建数据库会话池是没有意义的。当会话关闭时,mgo将在内部缓存资源,并在创建新会话时重用这些资源。全局变量的第一个解决方案,我之前尝试过,但它不起作用。我一直收到这个错误:http:panic serving[::1]:55642:运行时错误:无效的内存地址或零指针取消引用定义一个全局变量:var mongoConn*benkend.MongoDBConn
,在主函数中连接mongodb:mongocon=backend.NewMongoDBConn()
。我已经更改了上面的代码,它是有效的。创建数据库会话池是没有意义的。mgo将在会话关闭时在内部缓存资源,并在创建新会话时重用这些资源。首先感谢您回答这些问题。作为mgo的主要开发商,它具有特殊的权威性。我正在查看mgo/session.go,Apply()中的代码,例如,已经克隆了会话,那么为什么需要自己创建globalsession的副本呢?首先感谢您回答这些问题。作为mgo的主要开发商,它具有特殊的权威性。我正在查看mgo/session.go中的代码,例如Apply()已经克隆了会话,那么为什么需要自己创建globalsession的副本呢?