2012-12-24 6 views
1

는 좀 CRUD 방법과 간단한 MongoDB의 패키지를 작성했습니다 :핸들러에서 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 
} 

내가 HTTP 서버를 생성하고 다른 URL 핸들러를 가지고 server.go 있습니다. MongoDB에 연결하여 특정 처리기 내에서 AddToDo 메서드를 호출하고 싶습니다. 나는 내 서버의 주요 방법에서 DB에 연결할 수 있습니다

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 (제목, 설명 문자열) 메소드를 호출하는 방법을 모르겠어요. 전역 db 연결 변수를 만들어야합니까?

답변

2

두 가지 간단한 방법

1.global 데이터베이스 세션

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 모든 요청에 ​​새로운 DB 연결

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() 

} 

...... 

더 나은 솔루션 :

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

자세한 내용은 here을 클릭하십시오.

+0

전역 변수의 첫 번째 솔루션은 이전에 시도했지만 작동하지 않습니다. http : 패닉 서비스 [:: 1] : 55642 : 런타임 오류 : 잘못된 메모리 주소 또는 nil 포인터 참조 취소 – jwesonga

+0

전역 변수 정의 : var mongoConn * benkend.MongoDBConn', main 함수에서 mongodb 연결 : 'mongoConn = backend.NewMongoDBConn()'. 위의 코드를 변경하면 작동합니다. – pexeer

+1

db 세션 풀을 생성 할 필요는 없습니다. mgo는 세션이 닫힐 때 리소스를 내부적으로 캐시하고 새로운 세션이 생성 될 때마다 리소스를 다시 사용합니다. –

3

예, 글로벌 세션을 사용하면이를 쉽게 처리 할 수 ​​있습니다. 그런 다음 모든 처리기의 맨 위에는 다음과 같은 행을 수행 할 수 있습니다.

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

각 처리기가 작업 할 자체 세션을 갖도록합니다.

복사 및 닫기 세션은 값싼 작업이므로 생성 된 모든 세션에 대해 새 연결을 설정하는 대신 내부적으로 연결 풀에 대해 작동합니다.

+0

다음 질문에 대한 답변에 감사드립니다. mgo의 주요 개발자로서, 특히 권위있는 사람입니다. mgo/session.go의 코드를보고 있는데, 예를 들어 Apply()가 이미 세션을 복제 했으므로 globalsession의 복사본을 직접 만들어야하는 이유는 무엇입니까? – Alkaline

관련 문제