类型接口的通道没有在 Golang 中使用 MySql 接收值

我是golang的新手。我正在尝试使用 golang 对 mysql db 进行并发查询。我知道频道可以是接口类型。tableData (type map)当我在函数中打印时,RunQuery我得到了结果。我正在发送tableData到ch类型接口的 ie 通道。在函数getdataList中我没有得到任何价值ch。我不明白我做错了什么。


以下是我的代码:


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)

}


杨__羊羊
浏览 271回答 1
1回答

白板的微信

您的代码的问题在于它在从通道读取数据之前阻塞了执行流程。当您调用RunQueryfromgetdataList时,RunQuery尝试通过 channel 发送数据ch。但是,没有读取任何内容,ch因为要从中读取的代码位于其中,getdataList并且位于对RunQuery.因此,RunQuery永远不会返回并且要从中读取的 goroutinech永远不会触发。要修复,您也可以尝试RunQuery作为 goroutine 运行:func getdataList(id int) {&nbsp; &nbsp; &nbsp; &nbsp; ch := make(chan interface{})&nbsp; &nbsp; &nbsp; &nbsp; done := make (chan bool)&nbsp; &nbsp; &nbsp; &nbsp; // run in a goroutine&nbsp; &nbsp; &nbsp; &nbsp; go RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)&nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x, ok := <-ch //I am not getting any data in channel here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(x)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("done")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; done <- true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()}您的代码中还有另一个问题。你永远不会关闭ch。这可能会导致死锁。最理想的地方似乎是RunQuery:func RunQuery (ch chan interface{}, query string, param interface{}) {&nbsp; &nbsp; // ...&nbsp; &nbsp; ch <- tableData&nbsp; &nbsp; close(ch)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go