如何在Golang中的http处理程序中访问数据库连接?

问题描述 投票:0回答:3

我是 Golang 语言的新手,我来自 Nodejs,在 Nodejs 中,在 http 请求处理程序中访问数据库和操作 db 非常简单。现在我想在 Golang 中执行相同的操作,但无法从处理程序访问 db 变量。 假设我想让用户从 postgres 数据库发出 get 请求。

func getHandler(w http.ResponseWriter, r *http.Request) {
     
    fmt.Fprintf(w, "get req made")
     
    rows, error := db.Query("SELECT id, name, age FROM new_table LIMIT $1", 4)
    if error != nil {
        panic(error)
    }
    defer rows.Close()
    for rows.Next() {
        var id int
        var name string
        var age int
        error = rows.Scan(&id, &name, &age)
        if error != nil {
            panic(error)
        }
        fmt.Println(id, name, age)
    }
    error = rows.Err()
    if error != nil {
        panic(error)
    }
}```
And i get error: undeclared name: db, if i use this code inside the main function where the db connection is located, its working fine.
How can i use the db variable outside the scope where its declared?
database postgresql http go request
3个回答
2
投票

当您尝试连接到数据库时,您的

db
变量可能会在主函数中创建。问题是,
db
变量仅在您的 main 函数中具有作用域。因此,要工作,您需要在包级别全局声明它。

因此,在 main.go 中在主函数之外声明一个变量,然后在任何地方使用它。

package main

var db *DB

func main() {
  var err error
  db, err = sql.Connect(...)
  if err != nil {
      log.Fatal(err)
  }
  defer db.Close()

  //Start HTTP server
}

但是如果使用全局变量,则必须检查是否支持多线程访问。你的数据库连接可以正常工作,但是你必须阅读一些关于 go 中变量作用域和互斥体的教程。


0
投票

如果数据库来自另一个包,请确保它具有公共访问权限。您需要以大写字母开头,例如分贝

这将是使用 gorm.io 的单独文件中的基本数据库函数

package boot

import (
    "fmt"
    "log"
    "os"

    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

var DB *gorm.DB

func ConnectDB() {
    var err error
    dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
        os.Getenv("PG_HOST"),
        os.Getenv("PG_USER"),
        os.Getenv("PG_PASSWORD"),
        os.Getenv("PG_DBNAME"),
        os.Getenv("PG_PORT"),
    )
    DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Println(err)
        panic("Failled to connect to Database. ")
    }

}

0
投票

您可以使用闭包。

在您的

main
中创建数据库连接

func main() {
    db = GetDBConnection(dsn)  // suppose this returns *sql.DB, 
                               // omitting error handling code for simplicity
    defer db.Close()
    //register handler
    http.Handle("/foo", FooHandlerWrapper(db))
    
    // start HTTP server
}

现在用处理程序定义包装器,

func FooHandlerWrapper(db *sql.DB) func(w http.ResponseWriter, r *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        // use the db variable here
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.