Я новичок в golang. Я пытаюсь выполнить параллельные запросы в mysql db с помощью golang. Я знаю, что каналы могут быть типа интерфейса. Когда я печатаю tableData (type map)
в функции RunQuery
, я получаю результат. Я посылаю tableData
на номер ch
, т. Е. Канал типа интерфейса. В функции getdataList
Я не получаю никакого значения в ch
. Я не понимаю, что я делаю неправильно.канал типа интерфейса не получает значение в golang с MySql
Ниже мой код:
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))
}
Спасибо. Его работа прекрасна. У меня есть вопрос, хотя, где я должен добавить close (ch) в свой код. Кроме того, это не печатается. Будет ли он печататься только при закрытии канала? – Jagrati
У меня возникает сомнение, в 'fun dbtest', если я не использую' getdataList' с подпрограммами go. Используя тест apache, я получаю лучшую производительность, если я не использую две функции getdataList с функцией go. Можете ли вы объяснить мне, почему? – Jagrati
Я не могу сказать с уверенностью, но я предполагаю, что с goroutines одновременный доступ заставляет 'db' sql открывать два соединения. Без goroutines, первый вызов 'getdataList' создает одно соединение, которое затем используется вторым вызовом' getdataList'. Моим советом было бы обновить 'getdataList', чтобы он взял список идентификаторов и извлек большую часть данных одним запросом. В этом случае 'getdataList ([] int {2, 3})' с аналогичным обновленным sql-запросом обеспечит еще лучшую производительность. – abhink