golang – mysql 报错:运行时错误:无效的内存地址或空指针解引用。

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

golang - mysql panic: runtime error: invalid memory address or nil pointer dereference

问题

我正在尝试使用Golang建立一个简单的连接并从数据库获取数据,以下是包含我的API尝试的程序:

package main

import (
	"log"
	"net/http"
	"fmt"
	"github.com/gorilla/mux"
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

type Article struct {
	Author	string	`json:"author"`
	Title	string	`json:"title"`
	Body	string 	`json:"body"`
	Created string 	`json:"created"`
}

func getBooks(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
}

func getBook(w http.ResponseWriter, r *http.Request) {
	//
}

func createBook(w http.ResponseWriter, r *http.Request) {
	//
}

func updateBook(w http.ResponseWriter, r *http.Request) {
	//
}

func deleteBook(w http.ResponseWriter, r *http.Request) {
	//
}

func main() {
	r:= mux.NewRouter()

	db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/api_golang")
	if err != nil {
		panic(err.Error())
	}

	defer db.Close()

	getarticle, err := db.Query("SELECT * FROM article")

	for getarticle.Next() {
		var article Article

		err = getarticle.Scan(&article.Author)
		if err != nil {
			panic(err.Error())
		}
		fmt.Println(article.Author)
	}

	r.HandleFunc("/api/books", getBooks).Methods("GET")
	r.HandleFunc("/api/books/{id}", getBook).Methods("GET")
	r.HandleFunc("/api/books", createBook).Methods("POST")
	r.HandleFunc("/api/books{id}", updateBook).Methods("PUT")
	r.HandleFunc("/api/books{id}", deleteBook).Methods("DELETE")

	log.Fatal(http.ListenAndServe(":8000", r))
}

在Docker容器中构建和运行程序后,这是错误报告:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x618087]

goroutine 1 [running]:
database/sql.(*Rows).Next(0x0)
	/usr/local/go/src/database/sql/sql.go:2944 +0x27
main.main()
	/app/app.go:83 +0x165

我已经确保程序在连接MySQL数据库时运行正常。

【更新】
对于数据库连接,我使用的是包含Apache和MySQL的Linux版XAMPP。因此,数据库并非从Docker安装。

英文:

i trying to make a simple connection and getting data from database with golang, here the program that contain my API trial:

package main

	

import (
	// "encoding/json"
	"log"
	"net/http"
	"fmt"
	// "math/rand"
	// "strconv"
	"github.com/gorilla/mux"
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

// Book Struct(Model)
// type Book struct {
// 	ID 		string	`json:"id"`
// 	Isbn	string	`json:"isbn"`
// 	Title	string	`json:"title"`
// 	// Author	*Author `json:"author"`
// }

// Article Struct(Model)
type Article struct {
	Author	string	`json:"author"`
	Title	string	`json:"title"`
	Body	string 	`json:"body"`
	Created string 	`json:"created"`
}

// //Author struct
// type Author struct {
// 	Firstname	string	`json:"firstname"`
// 	Lastname	string	`json:"lastname"`
// }

// Init books var as a slice book struct
// var books []Book

//get All Books
func getBooks(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	// json.NewEncoder(w).Encode(books)
}
//get single book
func getBook(w http.ResponseWriter, r *http.Request) {
	//
}
//create new book
func createBook(w http.ResponseWriter, r *http.Request) {
	//
}
//get All Books
func updateBook(w http.ResponseWriter, r *http.Request) {
	//
}
//get All Books
func deleteBook(w http.ResponseWriter, r *http.Request) {
	//
}

func main() {
	//init router
	r:= mux.NewRouter()

	//mock Data - @todo - implement DB
	// books = append(books, Book{ID: "1", Isbn: "436455", Title: "Book One", Author: &Author{Firstname: "John", Lastname: "Doe"}})
	// books = append(books, Book{ID: "2", Isbn: "436444", Title: "Book two", Author: &Author{Firstname: "Samuel", Lastname: "Etoo"}})


	db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/api_golang")
	if err != nil {
		panic(err.Error())
	}

	defer db.Close()

	getarticle, err := db.Query("SELECT * FROM article")


	for getarticle.Next() {
		var article Article

		err = getarticle.Scan(&article.Author)
		if err != nil {
			panic(err.Error())
		}
		fmt.Println(article.Author)
	}
	//Route Handlers
	r.HandleFunc("/api/books", getBooks).Methods("GET")
	r.HandleFunc("/api/books/{id}", getBook).Methods("GET")
	r.HandleFunc("/api/books", createBook).Methods("POST")
	r.HandleFunc("/api/books{id}", updateBook).Methods("PUT")
	r.HandleFunc("/api/books{id}", deleteBook).Methods("DELETE")

	log.Fatal(http.ListenAndServe(":8000", r))
}


and here's the error report after build and run the program inside docker container:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x618087]

goroutine 1 [running]:
database/sql.(*Rows).Next(0x0)
	/usr/local/go/src/database/sql/sql.go:2944 +0x27
main.main()
	/app/app.go:83 +0x165

i'm already make sure that the program is running fine just when trying to connect mysql database.

[UPDATE]
for the database connection, i use xampp for linux that contains apache and mysql. So, the database is not installed from docker.

答案1

得分: 2

  1. 使用密码进行尝试

    db, err := sql.Open("mysql",
    "user:password@tcp(127.0.0.1:3306)/test")
    if err != nil {
    log.Fatal(err)
    }
    defer db.Close()

  2. 结构体 Article 有 4 个参数,所以在使用 "scan" 时,当 "select * from ..." 时,参数也需要 4 个参数。

    "select author from article"

英文:

1.try with password

db, err := sql.Open("mysql",
"user:password@tcp(127.0.0.1:3306)/test")
if err != nil {
log.Fatal(err)
}
defer db.Close() 
  1. the struct: Article has 4 param,so when use "scan",the param also need 4 param when "select * from ...".

    "select author from article"

huangapple
  • 本文由 发表于 2021年11月28日 00:10:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/70136515.html
匿名

发表评论

匿名网友

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

确定