写一个统计程序的时候,从表里查询gateway字段因为存在空的情况,所以在定义结构体的时候,设置为sql.NullString类型。
在起一个协程去查询到数据,然后放入到channel中,channel之前定义的是string类型的,所以需要转换一下。
代码实例:
package main import ( "bufio" "context" "database/sql" _"github.com/go-sql-driver/mysql" "fmt" "io" "os" "strings" "sync" "time" ) var ( db *sql.DB wg sync.WaitGroup ) type smclog struct { charge string gateway sql.NullString } func initDB()(err error){ ctx,cancel := context.WithTimeout(context.Background(),time.Second*20) defer cancel() dns := "root:1234@tcp(localhost:3306)/test" db,err = sql.Open("mysql",dns) if err !=nil{ return err } err =db.PingContext(ctx) if err !=nil{ return err } return nil } func readFile(filename string,mchan chan string){ defer wg.Done() defer close(mchan) file,err := os.Open(filename) if err !=nil{ fmt.Println("open file failed err:",err) return } defer file.Close() reader := bufio.NewReader(file) for{ line,err:= reader.ReadString('\n') if err == io.EOF{ //这儿文件末尾有一个空行,所以不用去处理最后一行 break } if err !=nil{ fmt.Println("read failed:err:",err) return } line =strings.TrimSuffix(line,"\n") line =strings.TrimSpace(line) mchan <- line } } func QueryData(datachan chan string) { defer wg.Done() defer close(datachan) sqlStr := "select charge,gateway from LOG202101" stmt ,err := db.Prepare(sqlStr) if err !=nil{ fmt.Println("prepare failed err :",err) return } defer stmt.Close() rows ,err := stmt.Query() if err !=nil{ fmt.Println("query failed err :",err) return } defer rows.Close() for rows.Next(){ var s smclog err := rows.Scan(&s.charge,&s.gateway) if err !=nil{ fmt.Printf("scan failed err:%v\n",err) return } datachan <- s.charge+"-"+s.gateway.String } } func main() { err := initDB() if err !=nil{ fmt.Println("init db failed err :",err) return } fmt.Println("init db success...") mobileWb := make(chan string) mobileFee := make(chan string) mobileData := make(chan string) wg.Add(3) go readFile("./mobile.txt",mobileWb) go readFile("./fee_mobile.txt",mobileFee) go QueryData(mobileData) mwb := make(map[string]int) for v :=range mobileWb{ mwb[v] =1 } mdb := make(map[string]string) for v:= range mobileData{ sd := strings.Split(v,"-") mdb[sd[0]]= sd[1] } //mfee :=make(map[string]int) //for v1:=range mobileFee{ // mfee[v1]=1 //} for k,_ := range mdb { _,ok := mwb[k] if ok{ data := mdb[k] //返回网关和对应的手机号 fmt.Println(data,k) } } wg.Wait() }