記golang資料庫查詢封裝的坑

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

前文

golang接觸也有一段時間,項目中有用到web api,基本上就是post json格式的,本想用java來寫,剛下手想到java太臃腫,各種繁瑣。覺得用golang小試一把,於是github一把,還是發現很多go rest 外掛程式,選了一個https://github.com/ant0ine/go-json-rest一根煙後,go-json-rest demo開始跑起來,使用curl命令類比了一把,正確運行。關於go-json-rest的使用,本文不做描述,官方文檔有很詳細的說明https://github.com/ant0ine/go-json-rest

本文

這是封裝資料庫的串連的核心代碼(其實大部分是網上copy的)此方法是將sql的查詢結果封裝成json格式輸出(當然是方便post傳回值)
func openDbString(sqlstring string) string {    conn := openDb()    defer conn.Close()    stmt, err := conn.Prepare(sqlstring)    if err != nil {        fmt.Println("Query Error", err)        return "Error"    }    defer stmt.Close()    rows, err := stmt.Query()    if err != nil {        fmt.Println("Query Error", err)        return "Error"    }    defer rows.Close()    // Get column names    columns, err := rows.Columns()    if err != nil {        panic(err.Error()) // proper error handling instead of panic in your app    }    // Make a slice for the values    values := make([]sql.RawBytes, len(columns))    // rows.Scan wants '[]interface{}' as an argument, so we must copy the    // references into such a slice    // See http://code.google.com/p/go-wiki/wiki/InterfaceSlice for details    scanArgs := make([]interface{}, len(values))    for i := range values {        scanArgs[i] = &values[i]    }    // Fetch rows    var jsonstring string    jsonstring = "{\"timestamp\": \"" + time.Now().Format("2006-01-02 15:04:05") + "\",\"data\":["    allcount := 0    for rows.Next() {        jsonstring += "{"        // get RawBytes from data        err = rows.Scan(scanArgs...)        if err != nil {            panic(err.Error()) // proper error handling instead of panic in your app        }        // Now do something with the data.        // Here we just print each column as a string.        var value string        for i, col := range values {            // Here we can check if the value is nil (NULL value)            if col == nil {                value = "NULL"            } else {                value = string(col)            }            //          fmt.Println(columns[i], ": ", value)            if i == len(values)-1 {                jsonstring += "\"" + columns[i] + "\":\"" + value + "\""            } else {                jsonstring += "\"" + columns[i] + "\":\"" + value + "\","            }            //          fmt.Println(" :", i, ": ", col, len(values))        }        //fmt.Println("replace before :", jsonstring, ": ", len(jsonstring))        //jsonstring = strings.Replace(jsonstring, ",", " ", len(jsonstring))        //fmt.Println("replace after :", jsonstring, ": ", len(jsonstring))        //      fmt.Println("-----------------------------------", allcount)        jsonstring += "},"        allcount++    }    if allcount > 0 {        jsonstring = Substr(jsonstring, 0, len(jsonstring)-1)    }    jsonstring += "]}"    if err = rows.Err(); err != nil {        panic(err.Error()) // proper error handling instead of panic in your app    }    return jsonstring}

接下來來記錄sql查詢結果的坑

網上的有很多golang查詢資料庫的栗子,但是都是簡單的使用
而我卻被坑了好幾次,細述如下

1.時間函數的坑

由於在sql欄位定義的datetime,直接使用getdate()運行起來報錯

 sql: Scan error on column index 0: unsupported driver -> Scan pair: time.Time -> *sql.RawBytes

OK,抽了根去,將datetime轉換層char,於是

returndata := openDbString("select top 1 CONVERT(CHAR(23), createtime, 121) as createtime from ATRes ")    fmt.Println("result:", returndata)

返回結果如下

 {"timestamp": "2015-06-11 11:51:22","data":[{"createtime":"2015-05-06 1"}]}

結果是時間被截斷了,再次嘗試

returndata := openDbString("select top 1 CONVERT(CHAR(36), createtime, 121) as createtime from ATRes ")    fmt.Println("result:", returndata)

返回結果如下,這次OK

{"timestamp": "2015-06-11 11:53:53","data":[{"createtime":"2015-05-06 16:15:42"}]}

2.長文本被截斷的坑

returndata := openDbString("select top 1 data from ATRes ")    fmt.Println("result:", returndata)

返回結果如下

  {"timestamp": "2015-06-11 11:57:10","data":[{"data":"http://jixieshi999.github.io/ilife/images/mamabeat."}]}

實際上data欄位在資料庫裡面是一個圖片的url,但是輸出結果裡面,url被截斷了(.jpg丟失了)
猜測下,可能是sql資料類型和golang的讀取資料類型不一致導致的,由於sql裡面data是nvacher(100)的類型,而輸出的是截斷的長度,哥哥我果斷數了一下data的長度,剛好是50,so 50=?100/2
再次修改查詢語句驗證猜想

returndata := openDbString("select top 1 cast(data as CHAR(200)) as datacopy,data from ATRes ")    fmt.Println("result:", returndata)

返回結果如下

  {"timestamp": "2015-06-11 12:01:54","data":[{"datacopy":"http://jixieshi999.github.io/ilife/images/mamabeat.jpg。。。。。。。。。。。。。。。","data":"http://jixieshi999.github.io/ilife/images/mamabeat."}]}

注意,datacopy後面的若干空格我用。代替方便查看,這種結果還是不滿足我的胃口,不可能有這麼多空格在json裡面,這不科學
於是我又倒騰了一把

returndata := openDbString("select top 1 rtrim(cast(data as CHAR(200))) as datacopy,data from ATRes ")    fmt.Println("result:", returndata)

返回結果如下,終於OK了

 {"timestamp": "2015-06-11 12:05:22","data":[{"datacopy":"http://jixieshi999.github.io/ilife/images/mamabeat.jpg","data":"http://jixieshi999.github.io/ilife/images/mamabeat."}]}

關於golang擷取目前時間的坑,百度下就有了

後記

總結下來golang對於資料庫的支援還是沒有java方便,也有本人對golang的瞭解不夠深入的問題
不過用golang做前文說的restful api實在是太方便了
又臭又長的原始碼就不上傳了

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.