当前位置: 首页 > 面试题库 >

使用Mux Router-如何将数据库传递给处理程序

夹谷斌蔚
2023-03-14
问题内容

目前,我尝试使用Go创建一个小型Web项目,以在服务器上进行数据处理。

我尝试将数据库连接传递给我的HandlerFunc(tions),但是它没有按预期工作。我对golang相当陌生,因此也许我不了解该lang的一些基本原理。

我的主要功能如下:

    func main() {

        db, err := config.NewDB("username:password@/databasename?charset=utf8&parseTime=True")
        if err != nil {
            log.Panic(err)
        }   
        env := &config.Env{DB: db} 

        router := NewRouter(env)
        log.Fatal(http.ListenAndServe(":8080", router))
    }

我的路由器:

    func NewRouter(env *config.Env) *mux.Router {
        router := mux.NewRouter().StrictSlash(true)
        for _, route := range routes {
            var handler http.Handler

            handler = route.HandlerFunc
            handler = Logger(handler, route.Name)

            router.
                Methods(route.Method).
                Path(route.Pattern).
                Name(route.Name).
                Handler(handler)
        }   
        return router
    }

和我的路线:

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

    type Routes []Route

    var routes = Routes{
        Route{
            "Index",
            "GET",
            "/",
            controller.Index,
        },  
        Route{
            "Show",
            "GET",
            "/todos/{todoId}",
            controller.TodoShow,
        },  
        Route{
            "Create",
            "POST",
            "/todos",
            controller.TodoCreate,
        },  
    }

所以-如何将我的“ env”(或env.DB)传递给FuncHandlers?我尝试了很多东西,但没有一个起作用。


问题答案:

您有三种选择:

  1. 将数据库连接池设置为全局,这样就不必传递它。sql.DB对于并发访问是安全的,这是最简单的方法。缺点是它使测试更加困难,并且混淆了池的“来源”-例如
        var db *sql.DB

    func main() {
        var err error
        db, err = sql.Open(...)
        // Now accessible globally, no need to pass it around
        // ...
     }
  1. 将您的处理程序包装在一个闭包中,以使内部处理程序可以访问它。您需要对此进行调整,以适应您的跨路线范围方法(这有点使IMO变得晦涩,使我更难以查看存在的路线,但是我离题了),例如:
        func SomeHandler(db *sql.DB) http.HandlerFunc {
        fn := func(w http.ResponseWriter, r *http.Request) {
            res, err := db.GetThings()
            // etc.
        }

        return http.HandlerFunc(fn)
    }

    func main() {
        db, err := sql.Open(...)
        http.HandleFunc("/some-route", SomeHandler(db))
        // etc.
    }
  1. 创建一个接受处理程序的自定义处理程序类型-例如
        type AppHandler struct {
        Handler func(env *config.Env, w http.ResponseWriter, r *http.Request)
        Env *config.Env
    }

    // ServeHTTP allows your type to satisfy the http.Handler interface.
    func (ah *AppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        ah.Handler(ah.Env, w, r)
    }

    func SomeHandler(env *config.Env, w http.ResponseWriter, r *http.Request) {
        res, err := env.DB.GetThings()
        // etc.
    }

请注意,(无耻的插件!)我已经详细介绍了最后一种方法,Alex
Edwards的博客文章也很出色,还介绍了在Go程序中访问数据库池的方法。

我能提供的唯一严格建议是,您应该避免在请求上下文中传递数据库池,这效率低下并且不是一种很好的做法(请求上下文是针对每个请求的临时对象)。



 类似资料:
  • 问题内容: 我试图将我的数据库对象传递给我的处理程序,而不是具有全局对象。但是我不知道这是否可行,我使用的是Gorilla Mux软件包,我可以看到它把闭包作为第二个参数。 然后定义了我可以使用的参数,理想情况下,我希望拥有这样的第三个参数。 有解决方法吗?还是我需要一个全局数据库对象?我是Go的新手,所以请详细说明可能的答案。 问题答案: 欢迎来到。 可以使用全局变量,特别是数据库对象。 但是,

  • 我将使用而不是绑定用户输入并将其写入数据库。当将请求处理程序方法(book book)中的数据绑定为book对象时,我感到困惑,那么我应该如何将该对象传递给数据库呢?通常使用,我根据我的模型类逐个变量绑定用户输入,然后使用相关的DAO方法将它们发送到db。我在下面展示我的课程。如果我使用,谁能说出我的请求处理程序方法应该是什么样子? 模型类: 控制器: 公共类簿记员{

  • 问题内容: 因此,我阅读了android AIDL文档,并对RPC在活动和服务之间的工作方式有一个大致的了解。但是,对于我的应用程序来说,实现这些功能似乎有些麻烦:基本上,我想向Service传递一个不错的处理程序,以便其线程可以将数据传递给Activity。目前,我正在通过使用静态公共成员(黑客)来解决此问题,但我更希望仅在服务的启动Intent中传递Handler对象。例如,我可以在创建时轻松

  • 我正在用Raku做实验,试图弄明白如何用子命令编写程序。当我运行时,: 我得到

  • 问题内容: 我正在使用pm2启动我的应用程序,但无法将参数传递给它。我正在使用的命令是pm2 start app.js-dev。尽管这永远有效。 问题答案: 您可以按照此票证所述进行操作:https : //github.com/Unitech/pm2/issues/13 尽管如果通过环境,则可能需要考虑利用环境变量。使用此工具,您可以创建一个变量,该环境中的任何进程都可以访问该变量。 因此,您有

  • 问题内容: 我在数组中呈现对象输入元素的集合。 这使我可以编写onChange处理函数: 但是在此处理程序中,我需要更改的范围对象的ID。因此,我可以更改更改在渲染函数中创建输入元素的方式并更改: 现在,我的处理程序将接收range.id作为参数,但是现在我没有newName值。我可以使用裁判获得它 这是我知道的唯一解决方案,但我怀疑有更好的解决方案。 问题答案: 该参数还通过了,但参数前置到参数