我是 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?
当您尝试连接到数据库时,您的
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 中变量作用域和互斥体的教程。
如果数据库来自另一个包,请确保它具有公共访问权限。您需要以大写字母开头,例如分贝
这将是使用 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. ")
}
}
您可以使用闭包。
在您的
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
}
}