所以我有两个文件。在一个我初始化一个大猩猩路由器,并注册处理程序。在另一个我定义处理程序。处理程序应该查询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)
}
}
我想为所有处理程序使用一个数据库连接,我该如何实现?
答案 0 :(得分:2)
Go {'1}}类型表示连接池而不是单个连接。建议您在程序初始化时创建一个池,并且:
创建一个全局池并使用它(该池可以安全地进行并发访问)
sql.DB
创建满足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/
(我会提供另一个例子,但我在移动设备上;原谅可怜的缩进)
另请查看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
}