【发布时间】:2016-10-21 07:05:29
【问题描述】:
我是 golang 和 MySQL 的新手,我正在使用开发框创建一个简单的网页,使用 golang(来自 2 个文件的代码在下面)来获取输入,将输入存储到数据库中并显示输入一个网页。目前在本地使用 MySQL 作为我的数据库,我的用户名是 root,密码是 abc,我的数据库也被命名为 abc。
在顶部我已经导入:
import (
_"github.com/go-sql-driver/mysql"
"database/sql"
)
当我提供我的网页时,我会调用我的 connectDB 函数:
func init(){
INDEX_HTML , _ = ioutil.ReadFile("./templates/index.html")
connectDb()
}
func connectDb(){
//socket : var/run/mysqld/mysqld.sock
/* connection string examples :
db, err := sql.Open("mysql", "user:password@/dbname")
user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true
TCP using default port (3306) on localhost:
user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped
Use the default protocol (tcp) and host (localhost:3306):
user:password@/dbname
No Database preselected:
user:password@/
*/
db, err := sql.Open("mysql", "root:abc@/abc")
log.Println("DB: ", db)
checkErr(err)
// Open doesn't open a connection. Validate DSN data:
checkErr(err)
}
我的理解和根据https://github.com/go-sql-driver/mysql SQL.open 返回一个 * sql.DB,当程序遇到上面的代码时:
/* At the top of my code i have var db = *sql.DB */
log.Println("DB: ", db)
我在命令提示符中得到以下内容,上面的代码 cmets 中记录了所有类型的示例连接字符串:
数据库:&{0x99c410 root:abc@/abc 0 {0 0} [] [] 0 0xc820072180 false map[] map[] 0 0 0 }
我的 MySQL 数据库使用给定的用户名和密码通过命令行在本地运行良好,我可以通过手动插入以下查询来获取一些项目。
mysql>
mysql> select * from ListItems
-> ;
+-------+
| items |
+-------+
| item1 |
| item2 |
+-------+
我正在尝试了解消息是什么以及如何连接到 mysql 数据库以运行查询并插入到数据库中。
也许我的连接字符串有问题?尝试插入数据库时的错误示例:
016/06/20 02:22:36 http: panic serving 10.1.0.5:41861:
runtime error: invalid
memory address or nil pointer dereference
goroutine 7 [running]:
net/http.(*conn).serve.func1(0xc82006c380)
/usr/local/go/src/net/http/server.go:1389 +0xc1
panic(0x74ef00, 0xc82000a0c0)
/usr/local/go/src/runtime/panic.go:443 +0x4e9
database/sql.(*DB).conn(0x0, 0x1, 0x0, 0x0, 0x0)
/usr/local/go/src/database/sql/sql.go:778 +0xac9
database/sql.(*DB).exec(0x0, 0x812b60, 0x26, 0xc82003fa70, 0x1, 0x1, 0xc82000b201, 0x0, 0x0, 0x0, ...)
/usr/local/go/src/database/sql/sql.go:1021 +0x87
database/sql.(*DB).Exec(0x0, 0x812b60, 0x26, 0xc82003fa70, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/database/sql/sql.go:1009 +0xbe
main.AddListHandler(0x7f56da7ac9b0, 0xc82006f6c0, 0xc8200f21c0)
/home/cabox/workspace/src/github.com/user/hello/main.go:26 +0x36c **<---**
net/http.HandlerFunc.ServeHTTP(0x859f70, 0x7f56da7ac9b0, 0xc82006f6c0, 0xc8200f21c0)
/usr/local/go/src/net/http/server.go:1618 +0x3a
net/http.(*ServeMux).ServeHTTP(0xc820010b10, 0x7f56da7ac9b0, 0xc82006f6c0, 0xc8200f21c0)
/usr/local/go/src/net/http/server.go:1910 +0x17d
net/http.serverHandler.ServeHTTP(0xc82006c180, 0x7f56da7ac9b0, 0xc82006f6c0, 0xc8200f21c0)
/usr/local/go/src/net/http/server.go:2081 +0x19e
net/http.(*conn).serve(0xc82006c380)
/usr/local/go/src/net/http/server.go:1472 +0xf2e
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2137 +0x44e
当我查看 main.go 中的第 26 行时,我有:
db.Exec("INSERT INTO ListItems(items) Values(?)" , (r.Form["item"][0]))
这是最小的代码示例:
项目/模板/index.html:
<!doctype html>
<h1>Enter item to add to list:</h1><br>
<form action="/addlist" method="post">
<input type="text" name="item" placeholder="Enter Item to add to list"><br>
<input type ="submit" class="add" value="Add To List"><br>
</form>
projects/main.go .. 使用 go build main.go
package main
import (
"net/http"
"fmt"
"io/ioutil"
"log"
_"github.com/go-sql-driver/mysql"
"database/sql"
)
var INDEX_HTML []byte // holds the raw html of index.html inside /templates
var db *sql.DB // pointer to sql.open which returns a sql.db
func main(){
fmt.Println("starting server on port 8080")
http.HandleFunc("/", IndexHandler)
http.HandleFunc("/addlist", AddListHandler)
http.ListenAndServe(":8080", nil)
}
func AddListHandler(w http.ResponseWriter, r *http.Request){
r.ParseForm()
log.Println("adding list: ", r.Form["item"][0])
db.Exec("INSERT INTO ListItems(items) Values(?)" , (r.Form["item"][0])) /*error*/
if(db == nil){log.Println("DB is nill")}
http.Redirect(w,r,"/", http.StatusTemporaryRedirect)
}
func IndexHandler(w http.ResponseWriter, r *http.Request){
log.Println("GET /")
w.Write(INDEX_HTML)
}
func init(){
INDEX_HTML , _ = ioutil.ReadFile("./templates/index.html")
connectDb()
}
func connectDb(){
//socket : var/run/mysqld/mysqld.sock
/* connection string examples :
db, err := sql.Open("mysql", "user:password@/dbname")
user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true
TCP using default port (3306) on localhost:
user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped
Use the default protocol (tcp) and host (localhost:3306):
user:password@/dbname
No Database preselected:
user:password@/
*/
db, err := sql.Open("mysql", "root:abc@/abc")
log.Println("DB: ", db)
checkErr(err)
// Open doesn't open a connection. Validate DSN data:
checkErr(err)
}
func checkErr(err error) {
if err != nil {
log.Println(err)
}else{
log.Println(err)
}
}
【问题讨论】:
-
那是 golang 打印你的
DB实例。正是您在log.Println("DB: ", db)中要求它执行的操作。你期望看到什么?一切似乎都运行良好。 -
hmm 我以为我会看到某种形式的数据库。这是我第一次使用 golang 和 mysql。我复制了我的错误以及导致它的代码 sn-p。
-
感谢您提供错误信息。但我还是想不通。如果您包含mcve,也许其他人可以提供帮助。
-
感谢您的澄清。我意识到我正在查看一个数据库实例,但最后的
值开始让我感到困惑。我期待那里有代表我的数据库的东西。 -
我已经包含了我用于此的代码示例