Golang& MySQL - 管理连接

时间:2016-01-25 15:42:30

标签: mysql sql go

我在使用MySQL的golang网络应用中处理连接时遇到问题。

在教程中我看到数据库交互在main函数中都处理了一次。

然而,在现实世界中,每个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")

可能因为db不能在主函数之外识别。我应该在每个网址处理程序上使用sql.Open()吗?

如果问题含糊不清,请道歉。

2 个答案:

答案 0 :(得分:4)

问题是,您在主函数中重新声明了db。

变化:

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

为:

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

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

答案 1 :(得分:2)

db, err := ...

语句操作符:=将定义一个新变量并隐藏具有相同名称的全局变量。