Golang将参数传递给gorilla路由器

时间:2015-06-10 22:52:45

标签: mysql go

所以我有两个文件。在一个我初始化一个大猩猩路由器,并注册处理程序。在另一个我定义处理程序。处理程序应该查询MYSQL数据库。 Routes.go看起来像这样 -

    package main

import (
    "net/http"
    "github.com/gorilla/mux"
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "fmt"
)

type Route struct {
    Name string
    Method string
    Pattern string
    HandlerFunc http.HandlerFunc
}

type Routes[]Route

func NewRouter() *mux.Router {
    db, err := sql.Open("mysql", "psanker:123@/education_data")
    err = db.Ping()

    if err != nil {
        fmt.Println("Failed to prepare connection to database")
        log.Fatal("Error:", err.Error())
    }

    defer db.Close()

    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        router.
            Methods(route.Method).
            Path(route.Pattern).
            Name(route.Name).
            Handler(route.HandlerFunc)
    }
    return router
}

var routes = Routes{
    Route {
        "Index",
        "GET",
        "/",
        Index,
    },
    Route {
        "getDistrict",
        "GET",
        "/district/{districtId}",
        getDistrict,
        DBConn &db,
    },
    Route {
        "getDistricts",
        "GET",
        "/districts",
        getDistricts,
    },
}

我的handlers.go文件看起来像这样 -

package main

import (
    "fmt"
    "net/http"
    "github.com/gorilla/mux"
    "encoding/json"
)

func Index(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "WELCOME!")
}

func getDistrict(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    districtId := vars["districtId"]
    fmt.Fprintln(w, "District id : ", districtId)
}

func getDistricts(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json;charset=UTF-8")
    w.WriteHeader(http.StatusOK)
    rows, err := db.Query("SELECT * from districts")
    check(err)
    var district District
    for rows.Next() {
        var id int64
        test := "hey"
        district = District{Id: id, Activities: test}
    }

    if err := json.NewEncoder(w).Encode(district); err != nil {
        check(err)
    }
}

我想为所有处理程序使用一个数据库连接,我该如何实现?

2 个答案:

答案 0 :(得分:2)

Go {'1}}类型表示连接池而不是单个连接。建议您在程序初始化时创建一个池,并且:

  1. 创建一个全局池并使用它(该池可以安全地进行并发访问)

    sql.DB
  2. 创建满足var db *sql.DB func main() { var err error db, err = sql.Open("connection string here") if err != nil { // handle it } // Rest of program/router/etc } func MyHandler(w http.ResponseWriter, r *http.Request) { err := db.Query("...") if err != nil { // handle it } // Rest of handler } 的自定义处理函数,并接受池或包含池作为附加参数的结构。我在这里写到:https://elithrar.github.io/article/custom-handlers-avoiding-globals/

  3. (我会提供另一个例子,但我在移动设备上;原谅可怜的缩进)

    另请查看sqlx以简化对结构处理的查询。

答案 1 :(得分:1)

Elithar的回答是实现这一目标的标准方法。如果要在每个处理程序中注入数据库连接,这是解决它的一种方法。您定义自己的处理程序并将其转换回路由器期望的内容。以下是我认为Elithar想要给出的例子。

func main() {
    http.HandlerFunc(myDbHandler(Index, db))
}

type dbHandler func(w http.ResponseWriter, r *http.Request, db *sql.DB)

func myDbHandler(handler dbHandler, db *sql.DB) func(w http.ResponseWriter, r *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        handler(w, r, db)
    }
}

func Index(w http.ResponseWriter, r *http.Request, db *sql.DB) {
    // handler code goes here
}