猿问

Golang 和 MySQL - 管理连接

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


在教程中,我看到数据库交互在主函数中全部处理一次。


然而,在现实世界中,每个 http 请求都会与数据库交互——我应该在哪里保存 sql.Open() 并延迟 sql.Close()?这是我的代码。


package main


import (

    "database/sql"

    "fmt"

    _ "github.com/go-sql-driver/mysql"

    "html/template"

    "net/http"

)


var db *sql.DB


var pageTemplate = template.Must(template.ParseFiles("index.html"))


type Items []string


func main() {

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

        "username:passwordl@tcp(127.0.0.1:3306)/databasename")

    checkErr(err)

    defer db.Close()

    _, err = db.Exec(

        `

    CREATE TABLE IF NOT EXISTS items (

      item_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,

      item TEXT

    );

    `)

    checkErr(err)

    http.HandleFunc("/", mainHandler)

    http.ListenAndServe(":3000", nil)

}


func mainHandler(w http.ResponseWriter, r *http.Request) {

    var item string

    var items Items

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

    checkErr(err)

    defer stmt.Close()

    rows, err := stmt.Query()

    checkErr(err)

    defer rows.Close()

    for rows.Next() {

        err := rows.Scan(&item)

        checkErr(err)

        items = append(items, item)

    }

    if err = rows.Err(); err != nil {

        checkErr(err)

    }

    pageTemplate.Execute(w, items)

}


func checkErr(err error) {

    if err != nil {

        fmt.Println(err)

    }

}

我在线上收到运行时错误:


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

大概是因为在主函数之外无法识别数据库。我应该在每个 url 处理程序上使用 sql.Open() 吗?


如果问题不明确,请道歉。


ITMISS
浏览 182回答 2
2回答

交互式爱情

问题是,您在主函数中重新声明了 db。改变:db, err := sql.Open("mysql",到:var err errordb, err = sql.Open("mysql",当涉及到应用程序中的数据库访问时,还可以考虑阅读不同的组织方法。这是一个很好的阅读:http : //www.alexedwards.net/blog/organising-database-access

人到中年有点甜

在里面db, err := ...语句运算符:=将定义一个新变量并隐藏具有相同名称的全局变量。
随时随地看视频慕课网APP

相关分类

Go
我要回答