Golang和MySQL – 管理连接

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

Golang & MySQL - Managing Connections

问题

我在处理使用MySQL的golang web应用程序中的连接时遇到了问题。

在我看过的教程中,数据库交互都是在主函数中处理的。

然而,在实际应用中,每个HTTP请求都会与数据库交互 - 我应该在哪里保留sql.Open()和defer sql.Close()?这是我的代码。

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. _ "github.com/go-sql-driver/mysql"
  6. "html/template"
  7. "net/http"
  8. )
  9. var db *sql.DB
  10. var pageTemplate = template.Must(template.ParseFiles("index.html"))
  11. type Items []string
  12. func main() {
  13. db, err := sql.Open("mysql",
  14. "username:passwordl@tcp(127.0.0.1:3306)/databasename")
  15. checkErr(err)
  16. defer db.Close()
  17. _, err = db.Exec(
  18. `
  19. CREATE TABLE IF NOT EXISTS items (
  20. item_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
  21. item TEXT
  22. );
  23. `)
  24. checkErr(err)
  25. http.HandleFunc("/", mainHandler)
  26. http.ListenAndServe(":3000", nil)
  27. }
  28. func mainHandler(w http.ResponseWriter, r *http.Request) {
  29. var item string
  30. var items Items
  31. stmt, err := db.Prepare("select item from items")
  32. checkErr(err)
  33. defer stmt.Close()
  34. rows, err := stmt.Query()
  35. checkErr(err)
  36. defer rows.Close()
  37. for rows.Next() {
  38. err := rows.Scan(&item)
  39. checkErr(err)
  40. items = append(items, item)
  41. }
  42. if err = rows.Err(); err != nil {
  43. checkErr(err)
  44. }
  45. pageTemplate.Execute(w, items)
  46. }
  47. func checkErr(err error) {
  48. if err != nil {
  49. fmt.Println(err)
  50. }
  51. }

我在以下代码行上遇到了运行时错误:

  1. stmt, err := db.Prepare("select item from items")

可能是因为在main函数之外无法识别db。我应该在每个URL处理程序上使用sql.Open()吗?

如果问题不明确,我向你道歉。

英文:

I'm having trouble handling connections in a golang web app that uses MySQL.

In the tutorials I have seen the database interaction is all handled once, in the main function.

However, in the real world each http request will interact with the database - where should I keep sql.Open() and defer sql.Close()? Here is my code.

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. _ "github.com/go-sql-driver/mysql"
  6. "html/template"
  7. "net/http"
  8. )
  9. var db *sql.DB
  10. var pageTemplate = template.Must(template.ParseFiles("index.html"))
  11. type Items []string
  12. func main() {
  13. db, err := sql.Open("mysql",
  14. "username:passwordl@tcp(127.0.0.1:3306)/databasename")
  15. checkErr(err)
  16. defer db.Close()
  17. _, err = db.Exec(
  18. `
  19. CREATE TABLE IF NOT EXISTS items (
  20. item_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
  21. item TEXT
  22. );
  23. `)
  24. checkErr(err)
  25. http.HandleFunc("/", mainHandler)
  26. http.ListenAndServe(":3000", nil)
  27. }
  28. func mainHandler(w http.ResponseWriter, r *http.Request) {
  29. var item string
  30. var items Items
  31. stmt, err := db.Prepare("select item from items")
  32. checkErr(err)
  33. defer stmt.Close()
  34. rows, err := stmt.Query()
  35. checkErr(err)
  36. defer rows.Close()
  37. for rows.Next() {
  38. err := rows.Scan(&item)
  39. checkErr(err)
  40. items = append(items, item)
  41. }
  42. if err = rows.Err(); err != nil {
  43. checkErr(err)
  44. }
  45. pageTemplate.Execute(w, items)
  46. }
  47. func checkErr(err error) {
  48. if err != nil {
  49. fmt.Println(err)
  50. }
  51. }

I get a runtime error on the line:

  1. stmt, err := db.Prepare("select item from items")

Persumably because the db isn't recognised outside of the main function. Should I instead have sql.Open() on each url Handler?

Apologies if the question is ambiguous.

答案1

得分: 4

问题是,你在主函数内部重新声明了db。

将以下代码进行更改:

  1. db, err := sql.Open("mysql",

更改为:

  1. var err error
  2. db, err = sql.Open("mysql",

此外,考虑阅读有关在应用程序中进行数据库访问时的不同组织方法。这是一篇很好的文章:http://www.alexedwards.net/blog/organising-database-access

英文:

The problem is, you are redeclaring db inside your main function.

change:

  1. db, err := sql.Open("mysql",

to:

  1. var err error
  2. db, err = sql.Open("mysql",

Also consider reading about diffrent organizing methods when it comes to db access in your app. This is a great read: http://www.alexedwards.net/blog/organising-database-access

答案2

得分: 2

db, err := ...语句中,操作符:=将定义一个新变量并隐藏同名的全局变量。

英文:

In the

  1. db, err := ...

statement the operator := will define an new variable and hidde the global one with the same name.

huangapple
  • 本文由 发表于 2016年1月25日 23:42:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/34996509.html
匿名

发表评论

匿名网友

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

确定