How to access database connection in http handler in Golang?

huangapple go评论95阅读模式
英文:

How to access database connection in http handler in Golang?

问题

我是你的中文翻译助手,以下是你要翻译的内容:

我对Golang语言还不熟悉,我之前使用的是Node.js,在那里很容易在HTTP请求处理程序中访问数据库并操作数据库。现在我想在Golang中做同样的事情,但我无法从处理程序中访问db变量。
假设我想在一个GET请求中从PostgreSQL数据库中获取用户。

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)
	}
}

我得到错误信息:未声明的名称:db,如果我将这段代码放在包含db连接的main函数内部,它可以正常工作。
如何在声明db变量的作用域之外使用它?

英文:

Im new to the Golang language and im coming from Nodejs, where it was quite simple to access database and manipulate db within a http request handler.Now i want to do the same in Golang and i cant access the db variable from the handlers.
Lets say i want to get users on a get request from a postgres db.

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?

</details>


# 答案1
**得分**: 2

可能你的`db`变量是在你的`main`函数中创建的,当你尝试连接数据库时。问题是,`db`变量的作用域仅限于`main`函数内部。所以为了使其正常工作,你需要在包级别上全局声明它。

所以在你的`main.go`文件中,在`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()

  // 启动HTTP服务器
}

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

英文:

Probably your db variable is created in your main func when you try to connect to the database. The problem is, that db variable will have a scope within your main func only. So to work, you need to declare it globally at package level.

So in your main.go declare a variable outside of your main func, then use it everywhere.

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
}

But if you use global variables, you must check whenever it supports multi threaded access. Your db connection will work fine, but you have to read some tutorial about variable scopes and mutexes in go.

答案2

得分: 0

如果db来自另一个包,请确保它具有公共访问权限。你需要以大写字母开头,例如Db。

这将是一个使用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("连接数据库失败。")
	}

}
英文:

If db is from another package make sure it has public access. You will need to start with a capital letter e.g. Db

This would be a basic database function in a separate file using gorm.io

package boot

import (
	&quot;fmt&quot;
	&quot;log&quot;
	&quot;os&quot;

	&quot;gorm.io/driver/postgres&quot;
	&quot;gorm.io/gorm&quot;
)

var DB *gorm.DB

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

}

huangapple
  • 本文由 发表于 2022年12月21日 06:27:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/74869489.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定