上一節已將將須要的數據從網站http://www.gratisography.com/ 抓取並存入數據庫【使用crawldata.go
中的InsertData(&imageDatas)
函數】,如今須要將數據從數據庫indiepic
的表gratisography
中取出並然會json
格式的數據。git
項目文件夾結構以下:github
indiepic ├── README.md ├── crawldata │ ├── crawldata.go │ └── database.go └── indiepic.go
如今將獲取數據的函數寫在database.go
中:web
func GetAllImages() (imageDatas ImageDatas, err error) { // 鏈接數據庫 db, err := OpenDatabase() if err != nil { fmt.Printf(s.Join([]string{"鏈接數據庫失敗", err.Error()}, "-->")) return nil, err } defer db.Close() // Prepare statement for inserting data imgOut, err := db.Query("SELECT * FROM gratisography") if err != nil { fmt.Println(s.Join([]string{"獲取數據失敗", err.Error()}, "-->")) return nil, err } defer imgOut.Close() // 定義掃描select到的數據庫字段的變量 var ( id int img_url string type_name string title string width int height int create_time string ) for imgOut.Next() { // db.Query()中select幾個字段就須要Scan多少個字段 err := imgOut.Scan(&id, &img_url, &type_name, &title, &width, &height, &create_time) if err != nil { fmt.Println(s.Join([]string{"查詢數據失敗", err.Error()}, "-->")) return nil, err } else { imageData := ImageData{img_url, type_name, title, width, height} imageDatas = append(imageDatas, imageData) } } return imageDatas, nil }
值得一提的是在SELECT
語句中拿到多少個字段就須要在Scan
的時候使用變量去獲取多少個字段,否測會報錯。因此建議不要像上面那樣SELECT *
,而是指定須要的字段如SELECT id,img_url,title FROM tableName
。GetAllImages()
函數返回兩個參數imageDatas ImageDatas
、err error
。數據庫
雖然使用GO本身寫一個HTTP請求很簡單,但爲了更好地處理路由和數據,這裏使用一個web框架martini Classy web framework for Go。
在使用以前須要先獲取:json
go get github.com/go-martini/martini
在indiepic.go
中引入martini
:api
import ( "github.com/go-martini/martini" )
定義一個結構體Results
用於表示輸出結果的數據結構:瀏覽器
type Results struct { Err int // 錯誤碼 Msg string // 錯誤信息 Datas crawldata.ImageDatas // 數據,無數據時爲nil }
由於須要輸出json
格式數據,因此須要用martini
的encoder
中間件資源,使用下面命令獲取:數據結構
go get github.com/martini-contrib/encoder
而後import
:app
import ( "github.com/martini-contrib/encoder" )
由於數據已經抓取完存入數據庫了,因此在main
函數中,就不在須要調用crawldata.Crawl()
了,將其註釋掉。而後編寫以下代碼:框架
func main() { // 使用crawldata包裏面的Crawl()抓取須要的數據存到數據庫 // crawldata.Crawl() m := martini.New() route := martini.NewRouter() var ( results Results err error ) m.Use(func(c martini.Context, w http.ResponseWriter, r *http.Request) { // 將encoder.JsonEncoder{}按照encoder.Encoder接口(注意大小寫)類型注入到內部 c.MapTo(encoder.JsonEncoder{}, (*encoder.Encoder)(nil)) w.Header().Set("Content-Type", "application/json; charset=utf-8") }) route.Get("/", func(enc encoder.Encoder) (int, []byte) { result := Results{10001, "Not Found Data", nil} return http.StatusOK, encoder.Must(enc.Encode(result)) }) route.Get("/api", func(enc encoder.Encoder) (int, []byte) { results.Datas, err = crawldata.GetAllImages() if err != nil { fmt.Println(s.Join([]string{"獲取數據失敗", err.Error()}, "-->")) result := Results{10001, "Data Error", nil} return http.StatusOK, encoder.Must(enc.Encode(result)) } else { results.Err = 10001 results.Msg = "獲取數據成功" return http.StatusOK, encoder.Must(enc.Encode(results)) } }) m.Action(route.Handle) m.Run() }
import
部分:
import ( "fmt" "github.com/go-martini/martini" "github.com/martini-contrib/encoder" "indiepic/crawldata" "net/http" s "strings" )
而後運行:
go run indiepic.go
在瀏覽器中訪問 http://127.0.0.1:3000/api 便可看到輸出的json
數據。若是安裝了postman
能夠使用postman
訪問地址,查看時選擇json
。
到這裏這個例子就結束了。源碼見GitHub。