GoFrame带你从0-1快速入门
文章目錄
- GoFrame:帶你從**0-1**快速入門
- 一.GoFrame介紹:
- 1.1GF基本介紹
- 1.2GF特點(diǎn)
- 1.3GF地址
- 1.4GF框架
- 二.GoFrame基礎(chǔ)環(huán)境搭建
- 2.1環(huán)境搭建
- 1)安裝golang
- 2)安裝goland
- 3) 了解go modules
- 2.2GF運(yùn)行普通項(xiàng)目
- go.mod
- hello.go
- 2.3GF搭建web項(xiàng)目
- go.mod
- main.go
- 三. GoFrame的Web服務(wù)介紹
- 3.1web基本介紹
- 3.2GF搭建web項(xiàng)目
- main.go
- config.toml
- 四.GoFrame路由注冊(cè)
- 4.1路由規(guī)則
- 4.2回調(diào)函數(shù)注冊(cè)
- 4.3執(zhí)行對(duì)象注冊(cè)
- 4.4分組注冊(cè)
- 4.5中間件設(shè)計(jì)
- 4.6請(qǐng)求和響應(yīng)對(duì)象
- 4.6.1請(qǐng)求Request
- 4.6.2 響應(yīng)Response
- 4.7教程示例
- 五. GoFrame的HTTP客戶端
- 5.1TTP協(xié)議介紹
- 5.2GF的HTTP客戶端
- main.go
- client_test.go
- 六.GoFrame配置文件
- 6.1配置文件介紹
- 6.2自動(dòng)檢測(cè)更新
- 6.3示例
- 項(xiàng)目目錄
- config.toml
- config1.toml
- config2.toml
- main.go
- config_test.go
- go.mod
- 七. GoFrame日志打印
- 7.1日志介紹
- 7.2單例對(duì)象
- 7.3日志級(jí)別
- 7.4配置文件
- 7.5示例
- 項(xiàng)目目錄
- main.go
- config.toml
- 八. Goframe數(shù)據(jù)庫(kù)操作
- 8.1基本介紹
- 8.2配置文件
- 9.3日志輸出配置
- 8.4數(shù)據(jù)結(jié)構(gòu)
- 8.5數(shù)據(jù)庫(kù)操作
- Insert/Replace/Save
- `Update`更新方法
- `Delete`刪除方法
- `Where/And/Or`查詢條件
- `All/One/Value/Count`數(shù)據(jù)查詢
- 數(shù)據(jù)庫(kù)表
- 九. GoFrame Redis操作
- 9.1Redis介紹
- 支持類型
- 使用場(chǎng)景
- 9.2Redis配置文件
- 9.3結(jié)果處理
- 9.4示例
- 目錄結(jié)構(gòu)
- main.go
- config.toml
- 十. Goframe常用工具介紹
- 10.1gstr字符串處理
- 示例
- 10.2g.Map和gmap
- 示例
- 10.3gjson
- 示例
- 10.4gmd5
- 示例
- 10.5類型轉(zhuǎn)換
- gconv
- Struct轉(zhuǎn)換
- 示例
GoFrame:帶你從0-1快速入門
由于項(xiàng)目的需要,自己開(kāi)始了解GoFrame這個(gè)框架,網(wǎng)上沒(méi)有視頻學(xué)習(xí),所以開(kāi)始看官網(wǎng)學(xué)習(xí),在學(xué)習(xí)的時(shí)候,感覺(jué)GoFrame真的是一個(gè)不錯(cuò)的框架,整理自己的筆記。大部分和github上的一樣,但是本文進(jìn)行整合,方便大家的學(xué)習(xí)。
一.GoFrame介紹:
Go(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開(kāi)發(fā)的一種跨平臺(tái)(Mac OS、Windows、Linux 等)靜態(tài)強(qiáng)類型、編譯型語(yǔ)言。由Ken Thompson(肯·湯普森)聯(lián)合創(chuàng)立,Unix操作系統(tǒng)的發(fā)明人之一(排在第一號(hào))。
- docker,golang頭號(hào)優(yōu)秀項(xiàng)目,通過(guò)虛擬化技術(shù)實(shí)現(xiàn)的操作系統(tǒng)與應(yīng)用的隔離,也稱為容器;
- kubernetes,是來(lái)自 Google 云平臺(tái)的開(kāi)源容器集群管理系統(tǒng)。簡(jiǎn)稱k8s,k8s和docker是當(dāng)前容器化技術(shù)的重要基礎(chǔ)設(shè)施;
golang基礎(chǔ)教程-快速入門go語(yǔ)言
github:https://github.com/goflyfox/gostudy
gitee:https://gitee.com/flyfox/gostudy
1.1GF基本介紹
GF(Go Frame)是一款模塊化、高性能、生產(chǎn)級(jí)的Go基礎(chǔ)開(kāi)發(fā)框架。實(shí)現(xiàn)了比較完善的基礎(chǔ)設(shè)施建設(shè)以及開(kāi)發(fā)工具鏈,提供了常用的基礎(chǔ)開(kāi)發(fā)模塊,如:緩存、日志、隊(duì)列、數(shù)組、集合、容器、定時(shí)器、命令行、內(nèi)存鎖、對(duì)象池、配置管理、資源管理、數(shù)據(jù)校驗(yàn)、數(shù)據(jù)編碼、定時(shí)任務(wù)、數(shù)據(jù)庫(kù)ORM、TCP/UDP組件、進(jìn)程管理/通信等等。并提供了Web服務(wù)開(kāi)發(fā)的系列核心組件,如:Router、Cookie、Session、Middleware、服務(wù)注冊(cè)、模板引擎等等,支持熱重啟、熱更新、域名綁定、TLS/HTTPS、Rewrite等特性。
1.2GF特點(diǎn)
- 模塊化、松耦合設(shè)計(jì);
- 模塊豐富,開(kāi)箱即用;
- 簡(jiǎn)便易用,易于維護(hù);
- 社區(qū)活躍,大牛謙遜低調(diào)脾氣好;
- 高代碼質(zhì)量、高單元測(cè)試覆蓋率;
- 詳盡的開(kāi)發(fā)文檔及示例;
- 完善的本地中文化支持;
- 更適合企業(yè)及團(tuán)隊(duì)使用;
1.3GF地址
- 主庫(kù):https://github.com/gogf/gf
- 碼云:https://gitee.com/johng/gf
- GF官網(wǎng):https://goframe.org/index
目錄結(jié)構(gòu)及基本介紹:
GF ├── container -- 基礎(chǔ)類型:數(shù)組,通道,列表,map,隊(duì)列,環(huán),set,樹(shù),類型處理和轉(zhuǎn)換 │ ├── garray │ ├── gchan │ ├── glist │ ├── gmap │ ├── gpool │ ├── gqueue │ ├── gring │ ├── gset │ ├── gtree │ ├── gtype │ └── gvar ├── crypto -- 加密和解密:常用的md5,aes,3des │ ├── gaes │ ├── gcrc32 │ ├── gdes │ ├── gmd5 │ └── gsha1 ├── database -- 數(shù)據(jù)庫(kù):關(guān)系型數(shù)據(jù)庫(kù)(mysql,postgre,oracle)和redis │ ├── gdb │ └── gredis ├── debug -- 調(diào)試 │ └── gdebug ├── DONATOR.MD ├── encoding --編解碼:常用的base64和json │ ├── gbase64 │ ├── gbinary │ ├── gcharset │ ├── gcompress │ ├── ghash │ ├── ghtml │ ├── gini │ ├── gjson │ ├── gparser │ ├── gtoml │ ├── gurl │ ├── gxml │ └── gyaml ├── errors -- 錯(cuò)誤處理 │ └── gerror ├── frame -- 核心框架:web,mvc │ ├── g │ ├── gins │ └── gmvc ├── go.mod ├── i18n -- 國(guó)際化 │ └── gi18n ├── internal 系統(tǒng):空處理,鎖,結(jié)構(gòu)體 │ ├── cmdenv │ ├── empty │ ├── fileinfo │ ├── intlog │ ├── mutex │ ├── rwmutex │ ├── structs │ └── utils ├── LICENSE ├── net -- 網(wǎng)絡(luò):http,tpc,udp │ ├── ghttp │ ├── gipv4 │ ├── gipv6 │ ├── gsmtp │ ├── gtcp │ └── gudp ├── os -- 系統(tǒng):定時(shí)任務(wù),命令行交互,日志,文件處理,緩存,session,時(shí)間 │ ├── gbuild │ ├── gcache │ ├── gcfg │ ├── gcmd │ ├── gcron │ ├── genv │ ├── gfcache │ ├── gfile │ ├── gfpool │ ├── gfsnotify │ ├── glog │ ├── gmlock │ ├── gmutex │ ├── gproc │ ├── gres │ ├── grpool │ ├── gsession │ ├── gspath │ ├── gtime │ ├── gtimer │ └── gview ├── README.MD ├── README_ZH.MD ├── RELEASE.1.MD ├── RELEASE.2.MD ├── test -- 單元測(cè)試 │ └── gtest ├── text -- 文本處理:正則,字符串處理 │ ├── gregex │ └── gstr ├── TODO.MD ├── util -- 常用工具:類型轉(zhuǎn)換,隨機(jī)數(shù),uuid,校驗(yàn) │ ├── gconv │ ├── gmode │ ├── gpage │ ├── grand │ ├── gutil │ ├── guuid │ └── gvalid └── version.go1.4GF框架
二.GoFrame基礎(chǔ)環(huán)境搭建
2.1環(huán)境搭建
- 之前基礎(chǔ)教程有g(shù)olang環(huán)境安裝詳細(xì)介紹,這里我只是快速過(guò)一下;
1)安裝golang
這里僅以windows為例:(蘋果用戶直接在 ~/.bash_profile 或者 ~/.zshrc (看自己電腦情況而定)中配置即可)
當(dāng)然應(yīng)該將這些環(huán)境變量配置到系統(tǒng)環(huán)境變量中
2)安裝goland
- https://goproxy.io
- https://goproxy.cn
- https://mirrors.aliyun.com/goproxy/
大家想詳細(xì)了解可以看我的另一篇博客:https://blog.csdn.net/weixin_51261234/article/details/123555904?spm=1001.2014.3001.5501,此中有代理的詳細(xì)設(shè)置和介紹
3) 了解go modules
go.mod是Go項(xiàng)目的依賴描述文件:
module hellogo 1.14require github.com/gogf/gf v1.11.7配置完編譯成功后,生成go.sum依賴分析結(jié)果,里面會(huì)有當(dāng)前所有的依賴詳細(xì)信息;
2.2GF運(yùn)行普通項(xiàng)目
通過(guò)go.mod引用goframe,構(gòu)建下載,打印版本號(hào);項(xiàng)目文件如下:
go.mod
module hellogo 1.14require github.com/gogf/gf v1.11.7hello.go
package mainimport ("fmt""github.com/gogf/gf" )func main() {fmt.Println("hello world!")// 打印GF版本fmt.Println(gf.VERSION) }2.3GF搭建web項(xiàng)目
讓我們來(lái)運(yùn)行第一個(gè)web程序
go.mod
module hellogo 1.14require github.com/gogf/gf v1.11.7main.go
package mainimport ("github.com/gogf/gf/frame/g""github.com/gogf/gf/net/ghttp" )func main() {s := g.Server()s.BindHandler("/", func(r *ghttp.Request){r.Response.Writeln("Welcome GoFrame!")})s.BindHandler("/hello", func(r *ghttp.Request){r.Response.Writeln("Hello World!")})s.SetPort(80)s.Run() }運(yùn)行然后打開(kāi)瀏覽器,訪問(wèn):http://127.0.0.1/和http://127.0.0.1/hello查看效果
三. GoFrame的Web服務(wù)介紹
GF框架提供了非常強(qiáng)大的WebServer,由ghttp模塊實(shí)現(xiàn)。實(shí)現(xiàn)了豐富完善的相關(guān)組件,例如:Router、Cookie、Session、路由注冊(cè)、配置管理、模板引擎、緩存控制等等,支持熱重啟、熱更新、多域名、多端口、多實(shí)例、HTTPS、Rewrite等等特性。
3.1web基本介紹
- 我們的電腦瀏覽器(Browser)就是客戶端(Client),大型的服務(wù)器就是服務(wù)端(Server);瀏覽器發(fā)送HTTP請(qǐng)求,即客戶端通過(guò)網(wǎng)絡(luò)將需求發(fā)給服務(wù)端,然后服務(wù)端也是通過(guò)網(wǎng)絡(luò)將數(shù)據(jù)發(fā)給客戶端;
?
3.2GF搭建web項(xiàng)目
-
這里主要介紹基本項(xiàng)目啟動(dòng)和配置參數(shù)
web:. │ go.mod -- go module │ go.sum │ main.go -- 啟動(dòng)文件 │ ├─config │ config.toml --配置文件 │ ├─gflogs │ 2020-03-19.log -- gf系統(tǒng)日志 │ access-20200319.log -- 訪問(wèn)日志 │ error-20200319.log -- 異常日志 │ ├─logs │ 2020-03-19.log -- 業(yè)務(wù)日志 │ └─publichello.html -- 靜態(tài)文件index.html -- 靜態(tài)入口文件
main.go
package mainimport ("github.com/gogf/gf/frame/g""github.com/gogf/gf/net/ghttp""github.com/gogf/gf/os/glog" )func main() {s := g.Server()// 測(cè)試日志s.BindHandler("/welcome", func(r *ghttp.Request) {glog.Info("你來(lái)了!")glog.Error("你異常啦!")r.Response.Write("哈嘍世界!")})// 異常處理s.BindHandler("/panic", func(r *ghttp.Request) {glog.Panic("123")})// post請(qǐng)求s.BindHandler("POST:/hello", func(r *ghttp.Request) {r.Response.Writeln("Hello World!")})s.Run() }config.toml
GF框架的核心組件均實(shí)現(xiàn)了便捷的文件配置管理方式,包括Server、日志組件、數(shù)據(jù)庫(kù)ORM、模板引擎等等,非常強(qiáng)大便捷。
[server]# 端口號(hào)Address = ":8199"# 靜態(tài)目錄ServerRoot = "public"# 入口文件IndexFiles = ["index.html", "main.html"]# 系統(tǒng)訪問(wèn)日志AccessLogEnabled = true# 系統(tǒng)異常日志panicErrorLogEnabled = true# 系統(tǒng)日志目錄,啟動(dòng),訪問(wèn),異常LogPath = "gflogs"[logger]# 標(biāo)準(zhǔn)日志目錄path = "logs"# 日志級(jí)別level = "all"四.GoFrame路由注冊(cè)
4.1路由規(guī)則
gf框架自建了非常強(qiáng)大的路由功能,提供了比任何同類框架更加出色的路由特性,支持流行的命名匹配規(guī)則、模糊匹配規(guī)則及字段匹配規(guī)則,并提供了優(yōu)秀的優(yōu)先級(jí)管理機(jī)制。
該方法是路由注冊(cè)的最基礎(chǔ)方法,其中的pattern為路由注冊(cè)規(guī)則字符串,在其他路由注冊(cè)方法中也會(huì)使用到,參數(shù)格式如下:
[HTTPMethod:]路由規(guī)則[@域名]其中HTTPMethod(支持的Method:GET,PUT,POST,DELETE,PATCH,HEAD,CONNECT,OPTIONS,TRACE)和@域名為非必需參數(shù),一般來(lái)說(shuō)直接給定路由規(guī)則參數(shù)即可,BindHandler會(huì)自動(dòng)綁定所有的請(qǐng)求方式,如果給定HTTPMethod,那么路由規(guī)則僅會(huì)在該請(qǐng)求方式下有效。@域名可以指定生效的域名名稱,那么該路由規(guī)則僅會(huì)在該域名下生效。
BindHandler是最原生的路由注冊(cè)方法,在大部分場(chǎng)景中,我們通常使用 分組路由 方式來(lái)管理路由
示例:
// hello方法,post調(diào)用s.BindHandler("POST:/hello", func(r *ghttp.Request) {r.Response.Writeln("url" + r.Router.Uri)})4.2回調(diào)函數(shù)注冊(cè)
回調(diào)函數(shù)注冊(cè)方式是最簡(jiǎn)單且最靈活的的路由注冊(cè)方式,注冊(cè)的服務(wù)可以是一個(gè)實(shí)例化對(duì)象的方法地址,也可以是一個(gè)包方法地址。服務(wù)需要的數(shù)據(jù)可以通過(guò)模塊內(nèi)部變量形式或者對(duì)象內(nèi)部變量形式進(jìn)行管理,開(kāi)發(fā)者可根據(jù)實(shí)際情況進(jìn)行靈活控制。
我們可以直接通過(guò)BindHandler方法完成回調(diào)函數(shù)的注冊(cè),在框架的開(kāi)發(fā)手冊(cè)中很多地方都使用了回調(diào)函數(shù)注冊(cè)的方式來(lái)做演示,因?yàn)檫@種注冊(cè)方式比較簡(jiǎn)單。
示例:
// 方法注冊(cè)s.BindHandler("/total", Total)4.3執(zhí)行對(duì)象注冊(cè)
執(zhí)行對(duì)象注冊(cè)是在注冊(cè)時(shí)便給定一個(gè)實(shí)例化的對(duì)象,以后每一個(gè)請(qǐng)求都交給該對(duì)象(同一對(duì)象)處理,該對(duì)象常駐內(nèi)存不釋放。服務(wù)端進(jìn)程在啟動(dòng)時(shí)便需要初始化這些執(zhí)行對(duì)象,并且這些對(duì)象需要自行負(fù)責(zé)對(duì)自身數(shù)據(jù)的并發(fā)安全維護(hù)(往往對(duì)象的成員變量應(yīng)當(dāng)是并發(fā)安全的,每個(gè)請(qǐng)求執(zhí)行完畢后該對(duì)象不會(huì)銷毀,其成員變量也不會(huì)釋放)。
// 對(duì)象注冊(cè)c := new(Controller)s.BindObject("POST:/object", c)4.4分組注冊(cè)
GF框架支持分組路由的注冊(cè)方式,可以給分組路由指定一個(gè)prefix前綴(也可以直接給定/前綴,表示注冊(cè)在根路由下),在該分組下的所有路由注冊(cè)都將注冊(cè)在該路由前綴下。分組路由注冊(cè)方式也是推薦的路由注冊(cè)方式。
示例:
// 分組注冊(cè)及中間件group := s.Group("/api")group.ALL("/all", func(r *ghttp.Request) {r.Response.Writeln("all")})4.5中間件設(shè)計(jì)
GF提供了優(yōu)雅的中間件請(qǐng)求控制方式,該方式也是主流的WebServer提供的請(qǐng)求流程控制方式,基于中間件設(shè)計(jì)可以為WebServer提供更靈活強(qiáng)大的插件機(jī)制。經(jīng)典的中間件洋蔥模型:
事例:
// 分組注冊(cè)及中間件group := s.Group("/api")group.Middleware(MiddlewareTest)group.ALL("/all", func(r *ghttp.Request) {r.Response.Writeln("all")})4.6請(qǐng)求和響應(yīng)對(duì)象
4.6.1請(qǐng)求Request
請(qǐng)求輸入依靠 ghttp.Request 對(duì)象實(shí)現(xiàn),ghttp.Request繼承了底層的http.Request對(duì)象。ghttp.Request包含一個(gè)與當(dāng)前請(qǐng)求對(duì)應(yīng)的返回輸出對(duì)象Response,用于數(shù)據(jù)的返回處理。
可以看到Request對(duì)象的參數(shù)獲取方法非常豐富,可以分為以下幾類:
4.6.2 響應(yīng)Response
ghttp.Response對(duì)象實(shí)現(xiàn)了標(biāo)準(zhǔn)庫(kù)的http.ResponseWriter接口。數(shù)據(jù)輸出使用Write*相關(guān)方法實(shí)現(xiàn),并且數(shù)據(jù)輸出采用了Buffer機(jī)制,因此數(shù)據(jù)的處理效率比較高。任何時(shí)候可以通過(guò)OutputBuffer方法輸出緩沖區(qū)數(shù)據(jù)到客戶端,并清空緩沖區(qū)數(shù)據(jù)。
簡(jiǎn)要說(shuō)明:
4.7教程示例
package mainimport ("github.com/gogf/gf/container/gtype""github.com/gogf/gf/frame/g""github.com/gogf/gf/net/ghttp" )func main() {s := g.Server()// 常規(guī)注冊(cè)// hello方法,post調(diào)用s.BindHandler("POST:/hello", func(r *ghttp.Request) {r.Response.Writeln("url" + r.Router.Uri)})// 所有方法,url包含name參數(shù)s.BindHandler("/:name", func(r *ghttp.Request) {// 獲取URL name參數(shù)r.Response.Writeln("name:" + r.GetString("name"))r.Response.Writeln("url" + r.Router.Uri)})// 所有方法,url包含name參數(shù)s.BindHandler("/:name/update", func(r *ghttp.Request) {r.Response.Writeln("name:" + r.GetString("name"))r.Response.Writeln("url" + r.Router.Uri)})// 所有方法,url包含name和action參數(shù)s.BindHandler("/:name/:action", func(r *ghttp.Request) {r.Response.Writeln("name:" + r.GetString("name"))r.Response.Writeln("action:" + r.GetString("action"))r.Response.Writeln("url" + r.Router.Uri)})// 所有方法,url包含field屬性s.BindHandler("/user/list/{field}.html", func(r *ghttp.Request) {// 獲取URL field屬性r.Response.Writeln("field:" + r.GetString("field"))r.Response.Writeln("url" + r.Router.Uri)})// 方法注冊(cè)s.BindHandler("/total", Total)// 對(duì)象注冊(cè)c := new(Controller)s.BindObject("POST:/object", c)// 分組注冊(cè)及中間件group := s.Group("/api")group.Middleware(MiddlewareTest)group.ALL("/all", func(r *ghttp.Request) {r.Response.Writeln("all")})group.GET("/get", func(r *ghttp.Request) {r.Response.Writeln("get")})group.POST("/post", func(r *ghttp.Request) {r.Response.Writeln("post")})// request and responses.BindHandler("POST:/test", func(r *ghttp.Request) {r.Response.WriteJson(g.Map{"name":r.GetString("name"),"age":r.GetInt("age"),"sex":r.Header.Get("sex"),})})s.SetPort(8199)s.Run() }var (total = gtype.NewInt() )func Total(r *ghttp.Request) {r.Response.Write("total:", total.Add(1)) }// 對(duì)象注冊(cè) type Controller struct{}func (c *Controller) Index(r *ghttp.Request) {r.Response.Write("index") }func (c *Controller) Show(r *ghttp.Request) {r.Response.Write("show") }// 中間件 func MiddlewareTest(r *ghttp.Request) {// 前置邏輯r.Response.Writeln("###start")r.Middleware.Next()// 后置邏輯r.Response.Writeln("###end") }訪問(wèn)結(jié)果:
### 常規(guī)注冊(cè) POST http://localhost:8199/hello### GET http://localhost:8199/abc### GET http://localhost:8199/a/add### GET http://localhost:8199/a/update### GET http://localhost:8199/user/list/11.html### 方法注冊(cè) GET http://localhost:8199/total### 對(duì)象注冊(cè),默認(rèn)訪問(wèn)index POST http://localhost:8199/object/### 對(duì)象注冊(cè),直接訪問(wèn)Index POST http://localhost:8199/object/index### 對(duì)象注冊(cè),訪問(wèn)show方法 POST http://localhost:8199/object/show### 分組,默認(rèn)訪問(wèn)index PUT http://localhost:8199/api/all### 對(duì)象注冊(cè),直接訪問(wèn)Index GET http://localhost:8199/api/get### 對(duì)象注冊(cè),訪問(wèn)show方法 POST http://localhost:8199/api/post### request and response POST http://localhost:8199/test sex:manname=liubang&age=18###五. GoFrame的HTTP客戶端
5.1TTP協(xié)議介紹
超文本傳輸協(xié)議(英文:HyperText Transfer Protocol,縮寫:HTTP)是一種用于分布式、協(xié)作式和超媒體信息系統(tǒng)的應(yīng)用層協(xié)議。HTTP是萬(wàn)維網(wǎng)的數(shù)據(jù)通信的基礎(chǔ)。
請(qǐng)求:
響應(yīng):
5.2GF的HTTP客戶端
- 這個(gè)先啟動(dòng)一個(gè)gf的http server,然后我們通過(guò)go test 來(lái)測(cè)試ghttp client;
main.go
package mainimport ("github.com/gogf/gf/frame/g""github.com/gogf/gf/net/ghttp" )func main() {s := g.Server()group := s.Group("/api")// 默認(rèn)路徑group.ALL("/", func(r *ghttp.Request) {r.Response.Writeln("Welcome GoFrame!")})// GET帶參數(shù)group.GET("/hello", func(r *ghttp.Request) {r.Response.Writeln("Hello World!")r.Response.Writeln("name:", r.GetString("name"))})// POST KVgroup.POST("/test", func(r *ghttp.Request) {r.Response.Writeln("func:test")r.Response.Writeln("name:", r.GetString("name"))r.Response.Writeln("age:", r.GetInt("age"))})// POST JSONgroup.POST("/test2", func(r *ghttp.Request) {r.Response.Writeln("func:test2")r.Response.Writeln("passport:", r.GetString("passport"))r.Response.Writeln("password:", r.GetString("password"))})// POST Headergroup.POST("/test3", func(r *ghttp.Request) {r.Response.Writeln("func:test3")r.Response.Writeln("Cookie:", r.Header.Get("Cookie"))})// POST Headergroup.POST("/test4", func(r *ghttp.Request) {r.Response.Writeln("func:test4")h := r.Headerr.Response.Writeln("accept-encoding:", h.Get("accept-encoding"))r.Response.Writeln("accept-language:", h.Get("accept-language"))r.Response.Writeln("referer:", h.Get("referer"))r.Response.Writeln("cookie:", h.Get("cookie"))r.Response.Writeln(r.Cookie.Map())})s.SetPort(80)s.Run() }client_test.go
單元測(cè)試源碼文件可以由多個(gè)測(cè)試用例組成,每個(gè)測(cè)試用例函數(shù)需要以Test為前綴,例如:
func TestXXX( t *testing.T )
- 測(cè)試用例文件不會(huì)參與正常源碼編譯,不會(huì)被包含到可執(zhí)行文件中。
- 測(cè)試用例文件使用go test指令來(lái)執(zhí)行,沒(méi)有也不需要 main() 作為函數(shù)入口。所有在以_test結(jié)尾的源碼內(nèi)以Test開(kāi)頭的函數(shù)會(huì)自動(dòng)被執(zhí)行。
- 測(cè)試用例可以不傳入 *testing.T 參數(shù)。
六.GoFrame配置文件
6.1配置文件介紹
GF的配置管理由gcfg模塊實(shí)現(xiàn),gcfg模塊是并發(fā)安全的,僅提供配置文件讀取功能,不提供數(shù)據(jù)寫入/修改功能,支持的數(shù)據(jù)文件格式包括: JSON、XML、YAML/YML、TOML、INI,項(xiàng)目中開(kāi)發(fā)者可以靈活地選擇自己熟悉的配置文件格式來(lái)進(jìn)行配置管理。
默認(rèn)讀取執(zhí)行文件所在目錄及其下的config目錄,默認(rèn)讀取的配置文件為config.toml;toml類型文件也是默認(rèn)的、推薦的配置文件格式,如果想要自定義文件格式,可以通過(guò)SetFileName方法修改默認(rèn)讀取的配置文件名稱(如:config.json, cfg.yaml, cfg.xml, cfg.ini等等)。
注:TOML大小寫敏感,必須是UTF-8編碼;
6.2自動(dòng)檢測(cè)更新
配置管理器使用了緩存機(jī)制,當(dāng)配置文件第一次被讀取后會(huì)被緩存到內(nèi)存中,下一次讀取時(shí)將會(huì)直接從緩存中獲取,以提高性能。同時(shí),配置管理器提供了對(duì)配置文件的自動(dòng)檢測(cè)更新機(jī)制,當(dāng)配置文件在外部被修改后,配置管理器能夠即時(shí)地刷新配置文件的緩存內(nèi)容。
配置管理器的自動(dòng)檢測(cè)更新機(jī)制是gf框架特有的一大特色。
6.3示例
項(xiàng)目目錄
D:. │ config_test.go -- 測(cè)試文件 │ go.mod │ go.sum │ main.go -- web自動(dòng)更新配置演示 │ ├─config │ config.toml -- 標(biāo)準(zhǔn)配置文件 │ └─configTest -- 定制目錄和配置文件config1.toml config2.tomlconfig.toml
# 模板引擎目錄 viewpath = "/home/www/templates/" # MySQL數(shù)據(jù)庫(kù)配置 [database][[database.default]]host = "127.0.0.1"port = "3306"user = "root"pass = "123456"name = "test1"type = "mysql"role = "master"charset = "utf8"priority = "1"[[database.default]]host = "127.0.0.1"port = "3306"user = "root"pass = "123456"name = "test2"type = "mysql"role = "master"charset = "utf8"priority = "1" # Redis數(shù)據(jù)庫(kù)配置 [redis]disk = "127.0.0.1:6379,0"cache = "127.0.0.1:6379,1"config1.toml
study = "hello study" study1 = "hello study1"config2.toml
config2 = "111"main.go
package mainimport ("github.com/gogf/gf/frame/g""github.com/gogf/gf/net/ghttp" )func main() {s := g.Server()// 默認(rèn)路徑s.BindHandler("/", func(r *ghttp.Request) {r.Response.Writeln("配置",g.Config().GetString("name"))r.Response.Writeln("Welcome GoFrame!")})s.SetPort(80)s.Run()}config_test.go
package mainimport ("fmt""github.com/gogf/gf/frame/g""testing" )// 基本配置使用 func TestConfig(t *testing.T) {// 默認(rèn)當(dāng)前路徑或者config路徑,默認(rèn)文件config.toml// /home/www/templates/fmt.Println(g.Config().Get("viewpath"))fmt.Println(g.Cfg().Get("viewpath"))// 127.0.0.1:6379,1c := g.Cfg()// 分組方式fmt.Println(c.Get("redis.cache"))// 數(shù)組方式:test2fmt.Println(c.Get("database.default.1.name")) }// 設(shè)置路徑 func TestConfig2(t *testing.T) {// 設(shè)置加載文件,默認(rèn)name為default// 設(shè)置路徑g.Cfg().SetPath("configTest")// 設(shè)置加載文件g.Cfg().SetFileName("config1.toml")// 打印測(cè)試fmt.Println(g.Cfg().Get("viewpath"))fmt.Println(g.Cfg().Get("study"))fmt.Println(g.Cfg().Get("study1"))fmt.Println(g.Cfg().Get("config2"))// 新的name就是新的實(shí)例g.Cfg("name").SetPath("configTest")g.Cfg("name").SetFileName("config2.toml")fmt.Println(g.Cfg("name").Get("viewpath"))fmt.Println(g.Cfg("name").Get("study"))fmt.Println(g.Cfg("name").Get("study1"))fmt.Println(g.Cfg("name").Get("config2")) }go.mod
module gf_configgo 1.14require github.com/gogf/gf v1.11.7七. GoFrame日志打印
7.1日志介紹
-
glog是通用的高性能日志管理模塊,實(shí)現(xiàn)了強(qiáng)大易用的日志管理功能,是gf開(kāi)發(fā)框架的核心模塊之一。
-
重要的幾點(diǎn)說(shuō)明:
7.2單例對(duì)象
- 從GF v1.10版本開(kāi)始,日志組件支持單例模式,使用g.Log(單例名稱)獲取不同的單例日志管理對(duì)象。提供單例對(duì)象的目的在于針對(duì)不同業(yè)務(wù)場(chǎng)景可以使用不同配置的日志管理對(duì)象。
7.3日志級(jí)別
-
日志級(jí)別用于管理日志的輸出,我們可以通過(guò)設(shè)定特定的日志級(jí)別來(lái)關(guān)閉/開(kāi)啟特定的日志內(nèi)容。通過(guò)SetLevel方法可以設(shè)置日志級(jí)別,glog支持以下幾種日志級(jí)別常量設(shè)定:
LEVEL_ALL LEVEL_DEBU LEVEL_INFO LEVEL_NOTI LEVEL_WARN LEVEL_ERRO LEVEL_CRIT -
我們可以通過(guò)位操作組合使用這幾種級(jí)別,例如其中LEVEL_ALL等價(jià)于LEVEL_DEBU | LEVEL_INFO | LEVEL_NOTI | LEVEL_WARN | LEVEL_ERRO | LEVEL_CRIT。例如我們可以通過(guò)LEVEL_ALL & ^LEVEL_DEBU & ^LEVEL_INFO & ^LEVEL_NOTI來(lái)過(guò)濾掉LEVEL_DEBU/LEVEL_INFO/LEVEL_NOTI日志內(nèi)容。
7.4配置文件
-
日志組件支持配置文件,當(dāng)使用g.Log(單例名稱)獲取Logger單例對(duì)象時(shí),將會(huì)自動(dòng)通過(guò)默認(rèn)的配置管理對(duì)象獲取對(duì)應(yīng)的Logger配置。默認(rèn)情況下會(huì)讀取logger.單例名稱配置項(xiàng),當(dāng)該配置項(xiàng)不存在時(shí),將會(huì)讀取logger配置項(xiàng)。
[logger]# 日志目錄path = "logs"# all LEVEL_ALL = LEVEL_DEBU | LEVEL_INFO | LEVEL_NOTI | LEVEL_WARN | LEVEL_ERRO | LEVEL_CRIT# dev LEVEL_DEV = LEVEL_ALL# pro LEVEL_PROD = LEVEL_WARN | LEVEL_ERRO | LEVEL_CRITlevel = "all"# 是否打印到控制臺(tái)stdout = true[logger.logger1]path = "logger1"level = "dev"stdout = true[logger.logger2]path = "logger2"level = "prod"stdout = false
7.5示例
項(xiàng)目目錄
D:. │ go.mod │ go.sum │ main.go │ └─configconfig.tomlmain.go
package mainimport ("github.com/gogf/gf/frame/g""github.com/gogf/gf/os/glog" )func main() {// 對(duì)應(yīng)默認(rèn)配置項(xiàng) logger,默認(rèn)defaultg.Log().Debug("[default]Debug")g.Log().Info("[default]info")g.Log().Warning("[default]Warning")g.Log().Error("[default]Error")// 對(duì)應(yīng) logger.logger1 配置項(xiàng)g.Log("logger1").Debug("[logger1]Debug")g.Log("logger1").Info("[logger1]info")g.Log("logger1").Warning("[logger1]Warning")g.Log("logger1").Error("[logger1]Error")// 對(duì)應(yīng) logger.logger2 配置項(xiàng)g.Log("logger2").Debug("[logger2]Debug")g.Log("logger2").Info("[logger2]info")g.Log("logger2").Warning("[logger2]Warning")g.Log("logger2").Error("[logger2]Error")// 日志級(jí)別設(shè)置,過(guò)濾掉Info日志信息l := glog.New()l.Info("info1")l.SetLevel(glog.LEVEL_ALL ^ glog.LEVEL_INFO)l.Info("info2")// 支持哪些級(jí)別// LEVEL_DEBU | LEVEL_INFO | LEVEL_NOTI | LEVEL_WARN | LEVEL_ERRO | LEVEL_CRIT// 異常g.Log().Panic("this is panic!")g.Log().Info("............")}config.toml
[logger]# 日志目錄path = "logs"# all LEVEL_ALL = LEVEL_DEBU | LEVEL_INFO | LEVEL_NOTI | LEVEL_WARN | LEVEL_ERRO | LEVEL_CRIT# dev LEVEL_DEV = LEVEL_ALL# pro LEVEL_PROD = LEVEL_WARN | LEVEL_ERRO | LEVEL_CRITlevel = "all"# 是否打印到控制臺(tái)stdout = true[logger.logger1]path = "logger1"level = "dev"stdout = true[logger.logger2]path = "logger2"level = "prod"stdout = false八. Goframe數(shù)據(jù)庫(kù)操作
8.1基本介紹
gf框架的ORM功能由gdb模塊實(shí)現(xiàn),用于常用關(guān)系型數(shù)據(jù)庫(kù)的ORM操作。其最大的特色在于同時(shí)支持map和struct兩種方式操作數(shù)據(jù)庫(kù)。gdb默認(rèn)情況下使用的是map數(shù)據(jù)類型作為基礎(chǔ)的數(shù)據(jù)表記錄載體,開(kāi)發(fā)者無(wú)需預(yù)先定義數(shù)據(jù)表記錄struct便可直接對(duì)數(shù)據(jù)表記錄執(zhí)行各種操作。這樣的設(shè)計(jì)賦予了開(kāi)發(fā)者更高的靈活度和簡(jiǎn)便性。
支持的數(shù)據(jù)庫(kù)類型:Mysql,SQLite,PostgreSQL,SQLServer,Oracle
8.2配置文件
- 推薦使用配置文件及單例對(duì)象來(lái)管理和使用數(shù)據(jù)庫(kù)操作。
如果我們使用g對(duì)象管理模塊中的g.DB("數(shù)據(jù)庫(kù)分組名稱")方法獲取數(shù)據(jù)庫(kù)操作對(duì)象,數(shù)據(jù)庫(kù)對(duì)象將會(huì)自動(dòng)讀取config.toml配置文件中的相應(yīng)配置項(xiàng)(通過(guò)配置管理模塊),并自動(dòng)初始化該數(shù)據(jù)庫(kù)操作的單例對(duì)象。
[database][[database.default]]link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"[[database.user]]link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user"注意每一項(xiàng)分組配置均可以是多個(gè)節(jié)點(diǎn),支持負(fù)載均衡權(quán)重策略。如果不使用多節(jié)點(diǎn)負(fù)載均衡特性,僅使用配置分組特性,也可以簡(jiǎn)化為如下格式:
[database][database.default]link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"[database.user]link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user"如果僅僅是單數(shù)據(jù)庫(kù)節(jié)點(diǎn),不使用配置分組特性,那么也可以簡(jiǎn)化為如下格式:
[database]link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"不同數(shù)據(jù)類型對(duì)應(yīng)的linkinfo如下:
| mysql | mysql: 賬號(hào):密碼@tcp(地址:端口)/數(shù)據(jù)庫(kù)名稱 | mysql |
| pgsql | pgsql: user=賬號(hào) password=密碼 host=地址 port=端口 dbname=數(shù)據(jù)庫(kù)名稱 | pq |
| mssql | mssql: user id=賬號(hào);password=密碼;server=地址;port=端口;database=數(shù)據(jù)庫(kù)名稱;encrypt=disable | go-mssqldb |
| sqlite | sqlite: 文件絕對(duì)路徑 (如: /var/lib/db.sqlite3) | go-sqlite3 |
| oracle | oracle: 賬號(hào)/密碼@地址:端口/數(shù)據(jù)庫(kù)名稱 | go-oci8 |
9.3日志輸出配置
gdb支持日志輸出,內(nèi)部使用的是glog.Logger對(duì)象實(shí)現(xiàn)日志管理,并且可以通過(guò)配置文件對(duì)日志對(duì)象進(jìn)行配置。默認(rèn)情況下gdb關(guān)閉了DEBUG日志輸出,如果需要打開(kāi)DEBUG信息需要將數(shù)據(jù)庫(kù)的debug參數(shù)設(shè)置為true。以下是為一個(gè)配置文件示例:
[database][database.logger]Path = "/var/log/gf-app/sql"Level = "all"Stdout = true[database.primary]link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user_center"debug = true其中database.logger即為gdb的日志配置,當(dāng)該配置不存在時(shí),將會(huì)使用日志組件的默認(rèn)配置
8.4數(shù)據(jù)結(jié)構(gòu)
為便于數(shù)據(jù)表記錄的操作,ORM定義了5種基本的數(shù)據(jù)類型:
type Map map[string]interface{} // 數(shù)據(jù)記錄 type List []Map // 數(shù)據(jù)記錄列表type Value *gvar.Var // 返回?cái)?shù)據(jù)表記錄值 type Record map[string]Value // 返回?cái)?shù)據(jù)表記錄鍵值對(duì) type Result []Record // 返回?cái)?shù)據(jù)表記錄列表8.5數(shù)據(jù)庫(kù)操作
Insert/Replace/Save
這三個(gè)鏈?zhǔn)讲僮鞣椒ㄓ糜跀?shù)據(jù)的寫入,并且支持自動(dòng)的單條或者批量的數(shù)據(jù)寫入,三者區(qū)別如下:
Insert
使用INSERT INTO語(yǔ)句進(jìn)行數(shù)據(jù)庫(kù)寫入,如果寫入的數(shù)據(jù)中存在主鍵或者唯一索引時(shí),返回失敗,否則寫入一條新數(shù)據(jù);
Replace
使用REPLACE INTO語(yǔ)句進(jìn)行數(shù)據(jù)庫(kù)寫入,如果寫入的數(shù)據(jù)中存在主鍵或者唯一索引時(shí),會(huì)刪除原有的記錄,必定會(huì)寫入一條新記錄;
Save
使用INSERT INTO語(yǔ)句進(jìn)行數(shù)據(jù)庫(kù)寫入,如果寫入的數(shù)據(jù)中存在主鍵或者唯一索引時(shí),更新原有數(shù)據(jù),否則寫入一條新數(shù)據(jù);
在部分?jǐn)?shù)據(jù)庫(kù)類型中,并不支持Replace/Save方法
Update更新方法
Update用于數(shù)據(jù)的更新,往往需要結(jié)合Data及Where方法共同使用。Data方法用于指定需要更新的數(shù)據(jù),Where方法用于指定更新的條件范圍。同時(shí),Update方法也支持直接給定數(shù)據(jù)和條件參數(shù)。
Delete刪除方法
Delete方法用于數(shù)據(jù)的刪除。
Where/And/Or查詢條件
這三個(gè)方法用于傳遞查詢條件參數(shù),支持的參數(shù)為任意的string/map/slice/struct/*struct類型。
Where條件參數(shù)推薦使用字符串的參數(shù)傳遞方式(并使用?占位符預(yù)處理),因?yàn)閙ap/struct類型作為查詢參數(shù)無(wú)法保證順序性,且在部分情況下(數(shù)據(jù)庫(kù)有時(shí)會(huì)幫助你自動(dòng)進(jìn)行查詢索引優(yōu)化),數(shù)據(jù)庫(kù)的索引和你傳遞的查詢條件順序有一定關(guān)系。
當(dāng)使用多個(gè)Where方法連接查詢條件時(shí),作用同And。 此外,當(dāng)存在多個(gè)查詢條件時(shí),gdb會(huì)默認(rèn)將多個(gè)條件分別使用()符號(hào)進(jìn)行包含,這種設(shè)計(jì)可以非常友好地支持查詢條件分組。
All/One/Value/Count數(shù)據(jù)查詢
這四個(gè)方法是數(shù)據(jù)查詢比較常用的方法:
此外,也可以看得到這四個(gè)方法定義中也支持條件參數(shù)的直接輸入,參數(shù)類型與Where方法一致。但需要注意,其中Value方法的參數(shù)中至少應(yīng)該輸入字段參數(shù)。
數(shù)據(jù)庫(kù)表
CREATE TABLE `user` (`uid` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`site` varchar(255) DEFAULT NULL,PRIMARY KEY (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=10000 ; package testimport ("fmt""github.com/gogf/gf/frame/g""testing" )// Insert func TestInsert(t *testing.T) {// INSERT INTO `user`(`name`) VALUES('john')_, err := g.DB().Table("user").Data(g.Map{"uid": 10000, "name": "john"}).Insert()if err != nil {panic(err)} }// Update func TestUpdate(t *testing.T) {// UPDATE `user` SET `name`='john guo' WHERE name='john'_, err := g.DB().Table("user").Data("name", "john guo").Where("name", "john").Update()if err != nil {panic(err)} }// Delete func TestDelete(t *testing.T) {// DELETE FROM `user` WHERE uid=10_, err := g.DB().Table("user").Where("uid", 10000).Delete()if err != nil {panic(err)} }// Select Where func TestWhere(t *testing.T) {// INSERT INTO `user`(`name`) VALUES('john')g.DB().Table("user").Data(g.Map{"uid": 10001, "name": "john"}).Insert()g.DB().Table("user").Data(g.Map{"uid": 10002, "name": "john2"}).Insert()// 數(shù)量count, err := g.DB().Table("user").Where("uid", 10001).Count()if err != nil {panic(err)}fmt.Println("count:", count)// 獲取單個(gè)值v, err := g.DB().Table("user").Where("uid", 10001).Fields("name").Value()if err != nil {panic(err)}fmt.Println("name:", v.String())// 查詢對(duì)象r, err := g.DB().Table("user").Where("uid", 10002).One()if err != nil {panic(err)}fmt.Println("name:", r.Map()["name"])// 查詢對(duì)象//l, err := g.DB().Table("user").As("t").Where("t.uid > ?", 10000).All()// 也可以簡(jiǎn)寫為 select * from user as t where t.uid > 10000l, err := g.DB().Table("user").As("t").All("t.uid > ?", 10000)if err != nil {panic(err)}for index, value := range l {fmt.Println(index, value["uid"], value["name"])}g.DB().Table("user").Where("uid", 10001).Delete()g.DB().Table("user").Where("uid", 10002).Delete() }九. GoFrame Redis操作
- Redis客戶端由gredis模塊實(shí)現(xiàn),底層采用了鏈接池設(shè)計(jì)。
9.1Redis介紹
Redis是當(dāng)前比較熱門的NOSQL系統(tǒng)之一,它是一個(gè)開(kāi)源的使用ANSI c語(yǔ)言編寫的key-value存儲(chǔ)系統(tǒng)(區(qū)別于MySQL的二維表格的形式存儲(chǔ)。)。性能出色:Redis讀取的速度是110000次/s,寫的速度是81000次/s。
支持類型
String: 字符串、Hash: 散列、List: 列表、Set: 集合、Sorted Set: 有序集合
PUB/SUB:發(fā)布訂閱;
在5.0支持了全新數(shù)據(jù)類型:Streams
使用場(chǎng)景
緩存,登錄驗(yàn)證碼,消息隊(duì)列,過(guò)濾器,分布式鎖,限流等
9.2Redis配置文件
絕大部分情況下推薦使用g.Redis單例方式來(lái)操作redis。因此同樣推薦使用配置文件來(lái)管理Redis配置,在config.toml中的配置示例如下:
# Redis數(shù)據(jù)庫(kù)配置 [redis]default = "127.0.0.1:6379,0"cache = "127.0.0.1:6379,1,123456?idleTimeout=600"其中,Redis的配置格式為:host:port[,db,pass?maxIdle=x&maxActive=x&idleTimeout=x&maxConnLifetime=x]
各配置項(xiàng)說(shuō)明如下:
| host | 是 | - | 地址 |
| port | 是 | - | 端口 |
| db | 否 | 0 | 數(shù)據(jù)庫(kù) |
| pass | 否 | - | 授權(quán)密碼 |
| maxIdle | 否 | 0 | 允許限制的連接數(shù)(0表示不閑置) |
| maxActive | 否 | 0 | 最大連接數(shù)量限制(0表示不限制) |
| idleTimeout | 否 | 60 | 連接最大空閑時(shí)間(單位秒,不允許設(shè)置為0) |
| maxConnLifetime | 否 | 60 | 連接最長(zhǎng)存活時(shí)間(單位秒,不允許設(shè)置為0) |
其中的default和cache分別表示配置分組名稱,我們?cè)诔绦蛑锌梢酝ㄟ^(guò)該名稱獲取對(duì)應(yīng)配置的redis對(duì)象。不傳遞分組名稱時(shí),默認(rèn)使用redis.default配置分組項(xiàng))來(lái)獲取對(duì)應(yīng)配置的redis客戶端單例對(duì)象。
9.3結(jié)果處理
可以看到通過(guò)客戶端方法Do/Receive獲取的數(shù)據(jù)都是二進(jìn)制形式[]byte的,需要開(kāi)發(fā)者手動(dòng)進(jìn)行數(shù)據(jù)轉(zhuǎn)換。
當(dāng)然,gredis模塊也提供了DoVar/ReceiveVar方法,用以獲取可供方便轉(zhuǎn)換的gvar.Var通用變量結(jié)果。
通過(guò)gvar.Var的強(qiáng)大轉(zhuǎn)換功能可以轉(zhuǎn)換為任意的數(shù)據(jù)類型,如基本數(shù)據(jù)類型Int,String,Strings,或者結(jié)構(gòu)體Struct等等。
9.4示例
目錄結(jié)構(gòu)
D:. │ go.mod │ go.sum │ main.go │ └─configconfig.tomlmain.go
package mainimport ("github.com/gogf/gf/frame/g""github.com/gogf/gf/util/gconv" )func main() {// redis字符串操作g.Redis().Do("SET", "k", "v")v, _ := g.Redis().Do("GET", "k")g.Log().Info(gconv.String(v))// 獲取cache鏈接v2, _ := g.Redis("cache").Do("GET", "k")g.Log().Info(gconv.String(v2))// DoVar轉(zhuǎn)換v3, _ := g.Redis().DoVar("GET", "k")g.Log().Info(v3.String())// setexg.Redis().Do("SETEX", "keyEx", 2000, "v4")v4, _ := g.Redis().DoVar("GET", "keyEx")g.Log().Info(v4.String())// listg.Redis().Do("RPUSH", "keyList", "v5")v5, _ := g.Redis().DoVar("LPOP", "keyList")g.Log().Info(v5.String())// hashg.Redis().Do("HSET", "keyHash", "v1", "v6")v6, _ := g.Redis().DoVar("HGET", "keyHash", "v1")g.Log().Info(v6.String())// setg.Redis().Do("SADD", "keySet", "v7")v7, _ := g.Redis().DoVar("SPOP", "keySet")g.Log().Info(v7.String())// sort setg.Redis().Do("ZADD", "keySortSet", 1, "v8")v8, _ := g.Redis().DoVar("ZREM", "keySortSet", "v8")g.Log().Info(v8.Int())}config.toml
# Redis數(shù)據(jù)庫(kù)配置 [redis]default = "127.0.0.1:6379,0"cache = "127.0.0.1:6379,1,123456?idleTimeout=600"十. Goframe常用工具介紹
10.1gstr字符串處理
- 字符串處理工具類
示例
p := fmt.Printlnp("Contains: ", gstr.Contains("test", "es"))p("Count: ", gstr.Count("test", "t"))p("HasPrefix: ", gstr.HasPrefix("test", "te"))p("HasSuffix: ", gstr.HasSuffix("test", "st"))p("Join: ", gstr.Join([]string{"a", "b"}, "-"))p("Repeat: ", gstr.Repeat("a", 5))p("Replace: ", gstr.Replace("foo", "o", "0", -1))p("Replace: ", gstr.Replace("foo", "o", "0", 1))p("Split: ", gstr.Split("a-b-c-d-e", "-"))p("ToLower: ", gstr.ToLower("TEST"))p("ToUpper: ", gstr.ToUpper("test"))p("Trim: ", gstr.Trim(" test "))10.2g.Map和gmap
g.Map實(shí)現(xiàn)type Map = map[string]interface{}
支持并發(fā)安全開(kāi)關(guān)選項(xiàng)的map容器,最常用的數(shù)據(jù)結(jié)構(gòu)。
該模塊包含多個(gè)數(shù)據(jù)結(jié)構(gòu)的map容器:HashMap、TreeMap和ListMap。
| HashMap | 哈希表 | O(1) | 否 | 否 | 高性能讀寫操作,內(nèi)存占用較高,隨機(jī)遍歷 |
| ListMap | 哈希表+雙向鏈表 | O(2) | 否 | 是 | 支持按照寫入順序遍歷,內(nèi)存占用較高 |
| TreeMap | 紅黑樹(shù) | O(log N) | 是 | 是 | 內(nèi)存占用緊湊,支持鍵名排序及有序遍歷 |
此外,gmap模塊支持多種以哈希表為基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)的常見(jiàn)類型map定義:IntIntMap、IntStrMap、IntAnyMap、StrIntMap、StrStrMap、StrAnyMap。
使用場(chǎng)景:
任何map/哈希表/關(guān)聯(lián)數(shù)組使用場(chǎng)景,尤其是并發(fā)安全場(chǎng)景中。
示例
// 常規(guī)map方法p := fmt.Println// 初始化m2 := g.Map{"a": 1, "b": 2}p(m2)// 設(shè)置m2["c"] = 25p(m2)// 獲取p(m2["b"])// 刪除delete(m2, "c")// 遍歷for k, v := range m2 {p(k, v)}p("###########################")// 創(chuàng)建一個(gè)默認(rèn)的gmap對(duì)象,// 默認(rèn)情況下該gmap對(duì)象不支持并發(fā)安全特性,// 初始化時(shí)可以給定true參數(shù)開(kāi)啟并發(fā)安全特性。m := gmap.New()// 設(shè)置鍵值對(duì)for i := 0; i < 10; i++ {m.Set(i, i)}// 查詢大小fmt.Println(m.Size())// 批量設(shè)置鍵值對(duì)(不同的數(shù)據(jù)類型對(duì)象參數(shù)不同)m.Sets(map[interface{}]interface{}{10: 10,11: 11,})fmt.Println(m.Size())// 查詢是否存在fmt.Println(m.Contains(1))// 查詢鍵值fmt.Println(m.Get(1))// 刪除數(shù)據(jù)項(xiàng)m.Remove(9)fmt.Println(m.Size())// 批量刪除m.Removes([]interface{}{10, 11})fmt.Println(m.Size())// 當(dāng)前鍵名列表(隨機(jī)排序)fmt.Println(m.Keys())// 當(dāng)前鍵值列表(隨機(jī)排序)fmt.Println(m.Values())// 查詢鍵名,當(dāng)鍵值不存在時(shí),寫入給定的默認(rèn)值fmt.Println(m.GetOrSet(100, 100))// 刪除鍵值對(duì),并返回對(duì)應(yīng)的鍵值fmt.Println(m.Remove(100))// 遍歷mapm.Iterator(func(k interface{}, v interface{}) bool {fmt.Printf("%v:%v ", k, v)return true})// 清空mapm.Clear()// 判斷map是否為空fmt.Println(m.IsEmpty())10.3gjson
- gjson模塊實(shí)現(xiàn)了強(qiáng)大的JSON編碼/解析,支持?jǐn)?shù)據(jù)層級(jí)檢索、動(dòng)態(tài)創(chuàng)建修改Json對(duì)象,并支持常見(jiàn)數(shù)據(jù)格式的解析和轉(zhuǎn)換等特點(diǎn)。
示例
// 創(chuàng)建jsonjsonContent := `{"name":"john", "score":"100"}`j := gjson.New(jsonContent)fmt.Println(j.Get("name"))fmt.Println(j.Get("score"))// 創(chuàng)建jsonj2 := gjson.New(nil)j2.Set("name", "John")j2.Set("score", 99.5)fmt.Printf("Name: %s, Score: %v\n",j2.GetString("name"),j2.GetFloat32("score"),)fmt.Println(j2.MustToJsonString())// struct轉(zhuǎn)jsontype Me struct {Name string `json:"name"`Score int `json:"score"`}me := Me{Name: "john",Score: 100,}j3 := gjson.New(me)fmt.Println(j3.Get("name"))fmt.Println(j3.Get("score"))// 轉(zhuǎn)換回StructMe2 := new(Me)if err := j.ToStruct(Me2); err != nil {panic(err)}fmt.Printf(`%+v`, Me2)fmt.Println()// 格式轉(zhuǎn)換fmt.Println("JSON:")fmt.Println(j3.MustToJsonString())fmt.Println("======================")fmt.Println("XML:")fmt.Println(j3.MustToXmlString("document"))fmt.Println("======================")fmt.Println("YAML:")fmt.Println(j3.MustToYamlString())fmt.Println("======================")fmt.Println("TOML:")fmt.Println(j3.MustToTomlString())10.4gmd5
- MD5算法
示例
p := fmt.Println// md5加密p(gmd5.MustEncrypt("123456"))10.5類型轉(zhuǎn)換
gconv
gf框架提供了非常強(qiáng)大的類型轉(zhuǎn)換包gconv,可以實(shí)現(xiàn)將任何數(shù)據(jù)類型轉(zhuǎn)換為指定的數(shù)據(jù)類型,對(duì)常用基本數(shù)據(jù)類型之間的無(wú)縫轉(zhuǎn)換,同時(shí)也支持任意類型到struct對(duì)象的轉(zhuǎn)換。由于gconv模塊內(nèi)部大量使用了斷言而非反射(僅struct轉(zhuǎn)換使用到了反射),因此執(zhí)行的效率非常高。
Struct轉(zhuǎn)換
項(xiàng)目中我們經(jīng)常會(huì)遇到大量struct的使用,以及各種數(shù)據(jù)類型到struct的轉(zhuǎn)換/賦值(特別是json/xml/各種協(xié)議編碼轉(zhuǎn)換的時(shí)候)。為提高編碼及項(xiàng)目維護(hù)效率,gconv模塊為各位開(kāi)發(fā)者帶來(lái)了極大的福利,為數(shù)據(jù)解析提供了更高的靈活度。
示例
i := 123.456fmt.Printf("%10s %v\n", "Int:", gconv.Int(i))fmt.Printf("%10s %v\n", "Int8:", gconv.Int8(i))fmt.Printf("%10s %v\n", "Int16:", gconv.Int16(i))fmt.Printf("%10s %v\n", "Int32:", gconv.Int32(i))fmt.Printf("%10s %v\n", "Int64:", gconv.Int64(i))fmt.Printf("%10s %v\n", "Uint:", gconv.Uint(i))fmt.Printf("%10s %v\n", "Uint8:", gconv.Uint8(i))fmt.Printf("%10s %v\n", "Uint16:", gconv.Uint16(i))fmt.Printf("%10s %v\n", "Uint32:", gconv.Uint32(i))fmt.Printf("%10s %v\n", "Uint64:", gconv.Uint64(i))fmt.Printf("%10s %v\n", "Float32:", gconv.Float32(i))fmt.Printf("%10s %v\n", "Float64:", gconv.Float64(i))fmt.Printf("%10s %v\n", "Bool:", gconv.Bool(i))fmt.Printf("%10s %v\n", "String:", gconv.String(i))fmt.Printf("%10s %v\n", "Bytes:", gconv.Bytes(i))fmt.Printf("%10s %v\n", "Strings:", gconv.Strings(i))fmt.Printf("%10s %v\n", "Ints:", gconv.Ints(i))fmt.Printf("%10s %v\n", "Floats:", gconv.Floats(i))fmt.Printf("%10s %v\n", "Interfaces:", gconv.Interfaces(i))fmt.Println("##############")// struct和map轉(zhuǎn)換type User struct {Uid int `c:"uid"`Name string `c:"name"`}// 對(duì)象m := gconv.Map(User{Uid : 1,Name : "john",})fmt.Println(m)fmt.Println("##############")user := (*User)(nil)err := gconv.Struct(m, &user)if err != nil {panic(err)}g.Dump(user)總結(jié)
以上是生活随笔為你收集整理的GoFrame带你从0-1快速入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2021爱分析·数据智能平台厂商全景报告
- 下一篇: 百度文库付费文档免费下载