Go 之sql.NullString 转化为string
写一个统计程序的时候,从表里查询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()
}

浙公网安备 33010602011771号