Ich bin neu zu Golang. Ich versuche, gleichzeitige Abfragen zu mysql db mit Golang zu tun. Ich weiß Kanäle können vom Typ Schnittstelle sein. Wenn ich tableData (type map)
in RunQuery
Funktion drucke, bekomme ich das Ergebnis. Ich sende tableData
zu ch
, d. H. Kanal des Typs Schnittstelle. In der Funktion getdataList
bekomme ich keinen Wert in ch
. Ich verstehe nicht, was ich falsch mache.Kanal des Typs Schnittstelle kein Wert in Golang mit MySql
Im Anschluss ist mein Code:
package main
import (
"database/sql"
"fmt"
"net/http"
_ "github.com/go-sql-driver/mysql"
"log"
)
var db *sql.DB
func getdataList(id int) {
ch := make(chan interface{})
done := make (chan bool)
RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)
go func() {
for {
x, ok := <-ch //I am not getting any data in channel here
if ok {
fmt.Println(x)
}else {
fmt.Println("done")
done <- true
return
}
}
}()
}
func RunQuery (ch chan interface{}, query string, param interface{}) {
stmt, err := db.Prepare(query)
if err != nil {
panic(err.Error())
}
defer stmt.Close()
rows, err := stmt.Query(param)
columns, err := rows.Columns()
if err != nil {
fmt.Println("Failed to get columns", err)
return
}
count := len(columns)
tableData := make([]map[string]interface{}, 0)
values := make([]interface{}, count)
valuePtrs := make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i]
}
rows.Scan(valuePtrs...)
entry := make(map[string]interface{})
for i, col := range columns {
var v interface{}
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
} else {
v = val
}
entry[col] = v
}
tableData = append(tableData, entry)
}
fmt.Pritln(tableData) //here I am getting data in map
ch <- tableData
}
func dbtest(w http.ResponseWriter, req *http.Request) {
go getdataList(2)
go getdataList(3)
}
func main() {
var err error
db, err = sql.Open("mysql", "root:@/dbName")
if err != nil {
panic(err.Error())
}
defer db.Close()
http.HandleFunc("/dbTest", dbtest)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Dank. Es funktioniert gut. Ich habe jedoch eine Frage, wo sollte ich schließen (ch) in meinem Code. Auch das wird nicht gedruckt. Wird es nur gedruckt, wenn der Kanal geschlossen ist? – Jagrati
Ich habe Zweifel, in 'Fun dbtest', wenn ich' getdataList' nicht mit Go-Routinen verwende. Mit Apache Benchmark bekomme ich eine bessere Leistung, wenn ich nicht die beiden "getdataList" -Funktionen mit Go-Routine verwende. Kannst du mir erklären warum? – Jagrati
kann ich nicht mit Sicherheit sagen, aber meine Vermutung wäre, dass mit goroutines, gleichzeitige Zugriff zwingt SQL '' db', zwei Verbindungen zu öffnen. Ohne goroutines erzeugt der erste Aufruf von 'getdataList' eine Verbindung, die dann beim zweiten Aufruf von' getdataList' verwendet wird. Mein Rat wäre, "getdataList" zu aktualisieren, so dass es eine Liste von IDs benötigt und die meisten Daten mit einer einzigen Abfrage abruft. In diesem Fall würde 'getdataList ([] int {2, 3})' mit einer ähnlich aktualisierten SQL-Abfrage eine noch bessere Leistung bieten. – abhink