日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

GoFrame带你从0-1快速入门

發(fā)布時(shí)間:2023/12/31 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GoFrame带你从0-1快速入门 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 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.go

1.4GF框架

二.GoFrame基礎(chǔ)環(huán)境搭建

2.1環(huán)境搭建

  • 之前基礎(chǔ)教程有g(shù)olang環(huán)境安裝詳細(xì)介紹,這里我只是快速過(guò)一下;

1)安裝golang

這里僅以windows為例:(蘋果用戶直接在 ~/.bash_profile 或者 ~/.zshrc (看自己電腦情況而定)中配置即可)

  • 去中文社區(qū)下載安裝golang:https://studygolang.com/dl;
  • 下載go.{version}.windows-amd64.msi或者go.{version}.windows-amd64.zip包,此次使用go.{version}.windows-amd64.zip包
  • 解壓壓縮文件(這里使用的是D:\Project,后面都基于這個(gè)目錄)
  • 配置環(huán)境變量GOPATH和GOROOT
  • # 打開(kāi)cmd設(shè)置 set GOPATH=D:\Project\GOPATH set GOROOT=D:\Project\GO set PATH=%PATH%;%GOROOT%\bin

    當(dāng)然應(yīng)該將這些環(huán)境變量配置到系統(tǒng)環(huán)境變量中

  • 此時(shí)打開(kāi)cmd窗口,運(yùn)行g(shù)o version即可展示安裝golang版本
  • # go version go version go1.14 windows/amd64

    2)安裝goland

  • 官網(wǎng)下載goland:https://www.jetbrains.com/go/
  • 安裝注冊(cè)購(gòu)買或者破解;
  • 首先打開(kāi)File->Setting或者Ctrl+Alt+S,設(shè)置goroot和gopath,默認(rèn)會(huì)獲取環(huán)境變量配置
  • 需要開(kāi)啟go modules功能,然后配置代理;不配置代理會(huì)訪問(wèn)國(guó)外地址,會(huì)很慢;建議使用以下三個(gè)地址:(選擇一個(gè)即可)
    • 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
  • module是配置項(xiàng)目名稱
  • go配置的是使用的golang版本
  • require配置引用第三方依賴包路徑和版本,latest表示最新版本;
  • 配置完編譯成功后,生成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.7

    hello.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.7

    main.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ù)獲取方法非常豐富,可以分為以下幾類:

  • Get*: 常用方法,簡(jiǎn)化參數(shù)獲取,GetRequest*的別名。
  • GetQuery*: 獲取GET方式傳遞過(guò)來(lái)的參數(shù),包括Query String及Body參數(shù)解析。
  • GetForm*: 獲取表單方式傳遞過(guò)來(lái)的參數(shù),表單方式提交的參數(shù)Content-Type往往為application/x-www-form-urlencoded, application/form-data, multipart/form-data, multipart/mixed等等。
  • GetRequest*: 獲取客戶端提交的參數(shù),不區(qū)分提交方式。
  • Get*Struct: 將指定類型的請(qǐng)求參數(shù)綁定到指定的struct對(duì)象上,注意給定的參數(shù)為對(duì)象指針。絕大部分場(chǎng)景中往往使用Parse方法將請(qǐng)求數(shù)據(jù)轉(zhuǎn)換為請(qǐng)求對(duì)象,具體詳見(jiàn)后續(xù)章節(jié)。
  • GetBody/GetBodyString: 獲取客戶端提交的原始數(shù)據(jù),該數(shù)據(jù)是客戶端寫入到body中的原始數(shù)據(jù),與HTTP Method無(wú)關(guān),例如客戶端提交JSON/XML數(shù)據(jù)格式時(shí)可以通過(guò)該方法獲取原始的提交數(shù)據(jù)。
  • GetJson: 自動(dòng)將原始請(qǐng)求信息解析為gjson.Json對(duì)象指針?lè)祷亍?/li>
  • Exit*: 用于請(qǐng)求流程退出控制;
  • 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ō)明:

  • Write*方法用于數(shù)據(jù)的輸出,可為任意的數(shù)據(jù)格式,內(nèi)部通過(guò)斷言對(duì)參數(shù)做自動(dòng)分析。
  • Write*Exit方法用于數(shù)據(jù)輸出后退出當(dāng)前服務(wù)方法,可用于替代return返回方法。
  • WriteJson*/WriteXml方法用于特定數(shù)據(jù)格式的輸出,這是為開(kāi)發(fā)者提供的簡(jiǎn)便方法。
  • WriteTpl*方法用于模板輸出,解析并輸出模板文件,也可以直接解析并輸出給定的模板內(nèi)容。
  • ParseTpl*方法用于模板解析,解析模板文件或者模板內(nèi)容,返回解析后的內(nèi)容。
  • 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ù)。
    package testimport ("fmt""github.com/gogf/gf/net/ghttp""testing" )var path = "http://127.0.0.1/api"// GET請(qǐng)求 func TestGet(t *testing.T) {if response, err := ghttp.Get(path); err != nil {panic(err)} else {defer response.Close()t.Log(response.ReadAllString())}if response, err := ghttp.Post(path); err != nil {panic(err)} else {defer response.Close()t.Log(response.ReadAllString())} }// GET請(qǐng)求帶參數(shù) func TestHello(t *testing.T) {if response, err := ghttp.Get(path + "/hello?name=whoami"); err != nil {panic(err)} else {defer response.Close()t.Log(response.ReadAllString())} }// POST請(qǐng)求 func TestPost(t *testing.T) {if response, err := ghttp.Post(path+"/test", "name=john&age=18"); err != nil {panic(err)} else {defer response.Close()t.Log(response.ReadAllString())} }// POST JSON func TestPostJson(t *testing.T) {if response, err := ghttp.Post(path+"/test2",`{"passport":"john","password":"123456"}`); err != nil {panic(err)} else {defer response.Close()t.Log(response.ReadAllString())} }// POST Header頭 func TestPostHeader(t *testing.T) {c := ghttp.NewClient()c.SetHeader("Cookie", "name=john; score=100")if r, e := c.Post(path + "/test3"); e != nil {panic(e)} else {fmt.Println(r.ReadAllString())} }// POST Header頭 func TestPostHeader2(t *testing.T) {c := ghttp.NewClient()c.SetHeaderRaw(` accept-encoding: gzip, deflate, br accept-language: zh-CN,zh;q=0.9,en;q=0.8 referer: https://idonottell.you cookie: name=john; score=100 user-agent: my test http client`)if r, e := c.Post(path + "/test4"); e != nil {panic(e)} else {fmt.Println(r.ReadAllString())} }

    六.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.toml

    config.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ō)明:

  • glog采用了無(wú)鎖設(shè)計(jì),性能高效;
  • glog支持文件輸出、日志級(jí)別、日志分類、調(diào)試管理、調(diào)用跟蹤、鏈?zhǔn)讲僮鞯鹊蓉S富特性;
  • 可以使用glog.New方法創(chuàng)建glog.Logger對(duì)象用于自定義日志打印,也可以并推薦使用glog默認(rèn)提供的包方法來(lái)打印日志;
  • 當(dāng)使用包方法修改模塊配置時(shí),注意任何的glog.Set*設(shè)置方法都將會(huì)全局生效
  • 日志內(nèi)容默認(rèn)時(shí)間格式為 時(shí)間 [級(jí)別] 內(nèi)容 換行,其中時(shí)間精確到毫秒級(jí)別,級(jí)別為可選輸出,內(nèi)容為調(diào)用端的參數(shù)輸入,換行為可選輸出(部分方法自動(dòng)為日志內(nèi)容添加換行符號(hào)),日志內(nèi)容示例:2018-10-10 12:00:01.568 [ERRO] 產(chǎn)生錯(cuò)誤;
  • Print*/Debug*/Info*方法輸出日志內(nèi)容到標(biāo)準(zhǔn)輸出(stdout),為防止日志的錯(cuò)亂,Notice*/Warning*/Error*/Critical*/Panic*/Fatal*方法也是將日志內(nèi)容輸出到標(biāo)準(zhǔn)輸出(stdout);
  • 其中Panic*方法在輸出日志信息后會(huì)引發(fā)panic錯(cuò)誤方法,Fatal*方法在輸出日志信息之后會(huì)停止進(jìn)程運(yùn)行,并返回進(jìn)程狀態(tài)碼值為1(正常程序退出狀態(tài)碼為0);
  • 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.toml

    main.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如下:

    數(shù)據(jù)庫(kù)類型Linkinfo配置更多參數(shù)
    mysqlmysql: 賬號(hào):密碼@tcp(地址:端口)/數(shù)據(jù)庫(kù)名稱mysql
    pgsqlpgsql: user=賬號(hào) password=密碼 host=地址 port=端口 dbname=數(shù)據(jù)庫(kù)名稱pq
    mssqlmssql: user id=賬號(hào);password=密碼;server=地址;port=端口;database=數(shù)據(jù)庫(kù)名稱;encrypt=disablego-mssqldb
    sqlitesqlite: 文件絕對(duì)路徑 (如: /var/lib/db.sqlite3)go-sqlite3
    oracleoracle: 賬號(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ù)表記錄列表
  • Map與List用于ORM操作過(guò)程中的輸入?yún)?shù)類型(與全局類型g.Map和g.List一致,在項(xiàng)目開(kāi)發(fā)中常用g.Map和g.List替換);
  • Value/Record/Result用于ORM操作的結(jié)果數(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ù)查詢比較常用的方法:

  • All 用于查詢并返回多條記錄的列表/數(shù)組。
  • One 用于查詢并返回單條記錄。
  • Value 用于查詢并返回一個(gè)字段值,往往需要結(jié)合Fields方法使用。
  • Count 用于查詢并返回記錄數(shù)。
  • 此外,也可以看得到這四個(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ō)明如下:

    配置項(xiàng)名稱是否必須默認(rèn)值說(shuō)明
    host-地址
    port-端口
    db0數(shù)據(jù)庫(kù)
    pass-授權(quán)密碼
    maxIdle0允許限制的連接數(shù)(0表示不閑置)
    maxActive0最大連接數(shù)量限制(0表示不限制)
    idleTimeout60連接最大空閑時(shí)間(單位秒,不允許設(shè)置為0)
    maxConnLifetime60連接最長(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.toml

    main.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。

    類型數(shù)據(jù)結(jié)構(gòu)平均復(fù)雜度支持排序有序遍歷說(shuō)明
    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)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    av在线一二三区 | 久久久久亚洲精品中文字幕 | 黄色午夜网站 | 亚洲电影第一页av | 中文字幕日韩精品有码视频 | 久久亚洲电影 | 亚洲综合视频在线播放 | 国产精品一区二区在线观看免费 | 亚洲国产精品视频在线观看 | 亚洲精品乱码久久久久久蜜桃不爽 | 久久精品视频18 | 日韩高清免费电影 | 青青河边草免费观看完整版高清 | 99视频这里只有 | 久久午夜鲁丝片 | 国产免费黄色 | 国产亚洲免费观看 | 国产精品国产三级国产aⅴ无密码 | 81国产精品久久久久久久久久 | 亚洲丝袜一区 | 日韩精品一区二区免费视频 | 亚洲波多野结衣 | 久久久久久久久久久久久久av | 国产精品久久久久久一区二区 | 国产成人精品亚洲日本在线观看 | 99精品亚洲 | 91九色蝌蚪视频在线 | 国产手机在线视频 | av在线影片 | 在线亚洲天堂网 | 精品一区二区三区四区在线 | 日韩精品一区二区三区第95 | 天天色视频 | 日本资源中文字幕在线 | 中文字幕av电影下载 | 色综合激情网 | 99精品在线视频观看 | 午夜 免费 | 国产综合在线视频 | 日韩三级免费 | 欧美激情片在线观看 | 成人久久免费视频 | 中国一 片免费观看 | 国产精品一区二区av麻豆 | 久久五月精品 | 国产精品久久久久久久免费大片 | 日本丰满少妇免费一区 | 手机av看片 | 玖玖在线观看视频 | 日韩一区二区三免费高清在线观看 | 在线黄色免费av | 久久精品国产精品亚洲精品 | 四虎永久视频 | 久久大香线蕉app | 亚洲精选视频免费看 | 亚洲精选99 | 久久精品视频观看 | 国产精品6999成人免费视频 | 久久久免费视频播放 | 日韩在线色视频 | 久久免费看av | 久久久精品网站 | 色资源网在线观看 | 久久高清视频免费 | 欧美日韩国产精品一区二区亚洲 | 中文字幕精品在线 | av黄色免费看 | 欧美超碰在线 | av免费在线观看网站 | 国产只有精品 | 亚洲另类xxxx | 国产精品日韩 | 精品在线观| 五月婷网站| 精品女同一区二区三区在线观看 | 久草免费在线观看视频 | 国产免费亚洲高清 | 日本九九视频 | 五月婷婷丁香 | 中文字幕一区二区在线观看 | 国产网红在线 | 免费看的av片 | 91最新地址永久入口 | 在线免费观看成人 | 深爱激情av | 最新久久免费视频 | 亚洲伊人第一页 | 91视频-88av | 精品亚洲一区二区三区 | 国产福利av | 美女久久久久久久久久 | 久久国产高清 | 一区二区三区免费网站 | 亚洲精品在线视频网站 | 亚洲精品视频第一页 | 久久成人国产精品入口 | 美女精品 | 美女视频黄,久久 | 国产在线专区 | 中文字幕久久久精品 | 国产免费小视频 | 日本中文字幕久久 | av动图| 九色91在线| 美女网站视频久久 | 国产精品国产亚洲精品看不卡 | 精品国产免费久久 | 午夜av不卡 | 国产欧美精品在线观看 | 在线观看午夜 | 欧美做受高潮 | 成年人在线免费看片 | 国产成人av电影在线 | 亚洲伦理中文字幕 | 国产黄色a| 黄色国产在线观看 | 在线看片中文字幕 | 国产成人精品三级 | 成人毛片网 | 999毛片| www日韩在线观看 | av动态图片 | 一级特黄av| 天天操天天射天天舔 | 亚洲免费成人av电影 | 偷拍福利视频一区二区三区 | 日韩精品久久久久久久电影竹菊 | 亚洲国产中文字幕在线视频综合 | 久久精品高清视频 | 国产精品美女www爽爽爽视频 | 91福利国产在线观看 | 麻豆视频成人 | 国产 色| 综合精品久久久 | 亚洲手机天堂 | 91精品视频在线观看免费 | 精品国产精品一区二区夜夜嗨 | 久久伊人五月天 | 在线观看免费成人av | 少妇bbw搡bbbb搡bbbb | 丁香六月婷 | 日韩在线观看视频一区二区三区 | 五月天亚洲激情 | 久久久久久久国产精品影院 | 97色在线观看 | 超碰97av在线 | 日韩和的一区二在线 | 麻豆91在线观看 | 日韩欧美99 | 免费在线观看一级片 | 在线影院中文字幕 | 999成人免费视频 | 婷婷色网视频在线播放 | 欧美国产日韩一区二区 | 亚洲一级片在线看 | 色爽网站 | 久久久精品国产免费观看一区二区 | 成人xxxx| 国产一区二区久久久 | av.com在线 | 99视频在线精品 | 人人要人人澡人人爽人人dvd | 国产午夜精品在线 | 天天射天天射天天 | 欧美日韩国产在线精品 | 九九九热 | 国产一区二区高清不卡 | 久久久免费毛片 | 182午夜在线观看 | 五月天综合网 | 日韩一区二区三区在线观看 | 亚洲天堂网站 | 色吊丝在线永久观看最新版本 | 亚洲永久国产精品 | 欧美综合在线观看 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 国产99久久99热这里精品5 | 97夜夜澡人人双人人人喊 | 九九热在线精品视频 | 欧美片一区二区三区 | 人人插人人插 | 在线观看涩涩 | 久久久高清 | 国产精品毛片久久久久久久 | 国产精品第72页 | 91最新在线 | 欧美福利网站 | 国产免费叼嘿网站免费 | 一区二区在线电影 | 91九色蝌蚪视频在线 | 国产在线a | 国产又粗又猛又黄又爽视频 | 色网站在线看 | 日韩丝袜在线观看 | 欧美美女激情18p | 亚洲视频99 | 在线亚洲欧美视频 | 久久精品波多野结衣 | 在线播放91 | 三级黄色免费片 | 999久久国产精品免费观看网站 | 久久在现 | 日韩精品欧美专区 | 青青河边草观看完整版高清 | 99久久精品国产一区二区三区 | av解说在线观看 | 久久免费视频一区 | 在线免费观看黄网站 | 国产韩国精品一区二区三区 | 亚洲www天堂com | 中文字幕大全 | 国产成人777777 | 91精品系列| 日韩精品免费在线观看 | 色综合天天干 | 国产97色在线| 国产精品ⅴa有声小说 | 最新亚洲视频 | 蜜臀aⅴ国产精品久久久国产 | 国产美女在线免费观看 | 欧美日韩在线视频观看 | 欧美va天堂在线电影 | 婷婷深爱五月 | 五月天激情综合 | 久久精品79国产精品 | 91日韩精品视频 | 国产精品资源在线 | 激情五月婷婷激情 | 精品成人在线 | 久久久久久久久久久成人 | 天天色天天射天天操 | 久草在线免费新视频 | 久久av高清 | 免费日韩 精品中文字幕视频在线 | 黄色免费观看 | 人人澡人人爱 | 美女视频黄免费的 | 黄色一级网| 丁香婷婷基地 | 日本公妇在线观看 | 午夜在线免费视频 | 欧美激情h| 亚洲成人国产 | 免费观看日韩av | av一区二区在线观看中文字幕 | 欧美精品第一 | 碰超人人 | 91麻豆国产 | 日韩久久精品 | 欧美日韩不卡在线观看 | 99这里只有精品视频 | 国产999精品| av网站在线观看免费 | 中文字幕影视 | 特级毛片网 | 天天操天天色天天射 | 欧美大片大全 | 成人影视免费看 | 人人澡人人模 | 九九免费在线看完整版 | 91视频在线观看免费 | 婷婷在线五月 | 91精品一区在线观看 | 亚洲精品影院在线观看 | 日韩动态视频 | 亚洲精品久久久久久中文传媒 | 又污又黄的网站 | 亚洲视频网站在线观看 | 国产福利av在线 | 久久国产精品99国产 | 欧美一级性视频 | 亚洲影视资源 | 亚洲欧洲精品一区二区精品久久久 | 国产精品视频在线观看 | 91正在播放| 九九免费在线观看视频 | 91av蜜桃 | 在线观看视频福利 | 国产精品午夜8888 | 91精品国产麻豆国产自产影视 | 免费观看性生活大片3 | 久久精品视频在线观看 | 99在线观看免费视频精品观看 | 亚洲影院一区 | 天堂中文在线视频 | 天天拍天天爽 | 亚洲片在线观看 | 欧美亚洲xxx | 亚洲少妇xxxx | 91自拍视频在线观看 | 三上悠亚一区二区在线观看 | a黄色大片 | 日本精品视频免费 | 日韩综合一区二区三区 | 亚洲精品男人的天堂 | 五月天婷亚洲天综合网精品偷 | av不卡免费在线观看 | 久草综合视频 | 国产精品a久久久久 | 黄色天堂在线观看 | av视屏在线播放 | 97中文字幕 | 色偷偷888欧美精品久久久 | 亚洲国产最新 | 在线看毛片网站 | 一区二区久久久久 | 日日干日日 | 国产色秀视频 | 九九热有精品 | 精壮的侍卫呻吟h | 国产精品男女啪啪 | 天天干天天拍 | 亚洲一级片 | 天天综合精品 | 午夜精品一区二区三区在线观看 | 精品在线观看免费 | 久草精品电影 | 美女av免费看 | 天天爱天天射天天干天天 | 久久精品国产99国产 | 国产亚洲成人精品 | 久青草影院 | 免费看毛片网站 | 久久久久久久久久久久久国产精品 | 午夜精品久久久久久久99热影院 | 国产小视频福利在线 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 久久免费精彩视频 | 国产精品观看视频 | 在线99视频| 国产99久久久国产精品成人免费 | 黄色大片日本免费大片 | 在线免费试看 | 日韩欧美精品在线观看 | 精品国产成人在线影院 | 久久久久综合 | 日韩精品中文字幕在线播放 | 久久精品国产一区二区三 | 九九在线精品视频 | 在线看片中文字幕 | 色瓜 | 久久高清免费观看 | 日韩视频中文字幕 | 午夜视频播放 | 国产精选视频 | 久久久久9999亚洲精品 | 探花视频在线观看+在线播放 | 欧美一级免费黄色片 | 香蕉视频啪啪 | 国产精品毛片一区视频 | 成年人视频在线免费观看 | 久国产在线播放 | 在线不卡视频 | 91亚瑟视频 | av福利电影 | 国产美女主播精品一区二区三区 | 国产黄色在线观看 | 69xxxx欧美| 成人视屏免费看 | 黄色大片av | 久久不见久久见免费影院 | 999成人| 色网av| 国产精品网址在线观看 | 国产色网| 欧美一区二区三区在线 | 国产亚洲在线观看 | 蜜臀av夜夜澡人人爽人人 | 日韩精品在线看 | 婷婷免费在线视频 | 色婷婷国产精品一区在线观看 | 亚洲成aⅴ人在线观看 | 日韩视频一区二区在线 | 国产成人久久av免费高清密臂 | 欧美国产日韩一区二区三区 | 国产精品不卡 | 成人在线视频观看 | 99色视频| 国产精品2020 | 中文字幕二区三区 | 精品在线一区二区三区 | 91久久黄色 | 激情五月色播五月 | 天天操夜夜干 | 色偷偷男人的天堂av | 在线观看国产日韩 | 亚洲专区在线播放 | 日韩激情一二三区 | 久久桃花网 | 激情五月婷婷综合 | 久久久久久久久免费视频 | 黄色录像av | 精品国产99 | 日韩免费电影 | 久久字幕精品一区 | 久久天天躁夜夜躁狠狠85麻豆 | 日韩精品欧美精品 | 亚洲精品国产成人 | 国产91免费在线 | 国产精品久久久久久一区二区三区 | 国产视频一区二区三区在线 | 国产视频美女 | 黄色a大片 | 综合色久| 9999国产精品 | 亚洲欧美日韩一区二区三区在线观看 | 999免费视频 | 久操视频在线观看 | 国产成人一区二区精品非洲 | 久久精品国产亚洲aⅴ | 91精品国产自产老师啪 | 在线看国产视频 | 久久国产一区二区 | 日本三级香港三级人妇99 | 玖草在线观看 | 久久久久亚洲精品男人的天堂 | 久久久免费高清视频 | 午夜精品一二三区 | 在线国产一区二区三区 | 97精品国产97久久久久久春色 | 精品视频免费在线 | 久久久精品视频网站 | 精品久久久成人 | 精品资源在线 | 久久国产电影 | 欧美日韩在线网站 | 色哟哟国产精品 | 免费看黄色大全 | 91最新中文字幕 | 精品嫩模福利一区二区蜜臀 | 日韩在线高清 | 亚洲成人精品在线 | 丁香婷婷激情啪啪 | 91亚洲精 | av综合在线观看 | av免费网页 | 久久99精品久久久久蜜臀 | 欧美视频在线观看免费网址 | 日韩最新av在线 | 粉嫩一区二区三区粉嫩91 | 日韩免费一区二区在线观看 | 日韩精品亚洲专区在线观看 | 一区二区伦理电影 | 色91在线| 国产精品中文字幕av | 99久久综合狠狠综合久久 | 久久99电影| 亚州精品国产 | 中文字幕在线观看一区二区 | 99精品久久久 | 一区二区视频免费在线观看 | 成人综合婷婷国产精品久久免费 | 99精品国产在热久久下载 | 夜又临在线观看 | 精品国产一区二区三区在线观看 | 91精品视频在线观看免费 | 国产区免费| 精品毛片久久久久久 | 国产手机视频在线 | 欧美日韩久 | 午夜精品久久久99热福利 | 久久伊人精品一区二区三区 | 一区二区三区在线播放 | 日韩天天操 | 日韩成人精品一区二区 | 黄色av一区二区三区 | 国产精品18久久久久久首页狼 | 黄色免费观看视频 | 日韩欧美一区二区在线播放 | 国产精品区二区三区日本 | www黄色 | 国产日产亚洲精华av | 丁香五月缴情综合网 | 视频三区在线 | 久久久www成人免费毛片麻豆 | 精品中文字幕在线播放 | 97精品国自产拍在线观看 | 久久精品99国产精品亚洲最刺激 | 久久精品视频99 | 天天干,天天射,天天操,天天摸 | 久久久久草 | 欧美成人影音 | 午夜天使 | 毛片888 | 黄网站免费看 | 91久久精品一区二区三区 | 国产在线a | 男女啪啪免费网站 | av网站免费线看精品 | 99视频在线精品免费观看2 | 最新av免费在线观看 | 午夜精品99久久免费 | 久久国产福利 | 97在线免费观看视频 | 四虎影视4hu4虎成人 | 日b视频国产| 久久无码精品一区二区三区 | 亚洲精品国产电影 | 欧美日韩在线观看一区二区 | 91精品一区二区三区蜜臀 | 五月丁婷婷 | 国产精品久久久av | 六月色婷婷 | 久久伊人爱 | 狠狠色丁香婷综合久久 | 成人小视频在线观看免费 | 香蕉在线视频播放网站 | 国产日韩在线观看一区 | 最近日本中文字幕a | 亚洲精品免费在线观看视频 | 综合久久精品 | 激情五月***国产精品 | 国产在线久久久 | 亚洲国产精品久久 | 在线观看成年人 | 国产精品18久久久久vr手机版特色 | 亚洲精品午夜aaa久久久 | 伊人天天干 | 色综合久久久久久久 | 九九精品视频在线观看 | 国产一区二区三区 在线 | 美女精品 | 免费视频一区 | 婷婷黄色片 | 91av美女| 日本中文字幕视频 | 成人av在线电影 | 99久久精品午夜一区二区小说 | 久久精品国产成人精品 | 午夜少妇一区二区三区 | 午夜 免费 | 久久久久久久久艹 | 狠狠色噜噜狠狠狠狠2021天天 | 九九综合在线 | 久草网视频在线观看 | 午夜精品三区 | 日本中文字幕在线免费观看 | 免费在线观看av电影 | 九九热1 | 久久久精品国产免费观看同学 | 最近高清中文在线字幕在线观看 | 久久se视频 | 国产精品1区2区3区在线观看 | 天天操天天射天天操 | 亚洲天天综合网 | 国产成人精品国内自产拍免费看 | 亚洲精品美女久久久久 | 天天色天天骑天天射 | 国产99久久久国产精品成人免费 | 国产精品午夜久久 | 91日本在线播放 | 久久久久成人精品亚洲国产 | 日本性生活一级片 | 国产黄色片网站 | 伊人色播 | 免费一级日韩欧美性大片 | 国产精品高潮久久av | 91视频com| 在线色资源 | 成人宗合网 | 国产精品xxxx18a99 | 色综合久久久久综合99 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 久久久网页 | 91精品久久久久久久91蜜桃 | 91精品视频观看 | 在线视频 一区二区 | 人人爽人人 | 99久免费精品视频在线观看 | 国产精品欧美久久久久三级 | 91视频免费看 | 黄视频色网站 | 精品av在线播放 | 成片人卡1卡2卡3手机免费看 | 久操97| 久久精品看片 | 成年人免费在线观看网站 | 国产高清精品在线 | 黄色aa久久 | 超碰官网 | 日本中文一区二区 | 久久人人爽爽人人爽人人片av | 69国产成人综合久久精品欧美 | 在线免费黄色av | 亚洲精品乱码久久久久久高潮 | 午夜成人免费影院 | 中文字幕在线观看三区 | 亚洲精品91天天久久人人 | 日韩高清在线一区二区三区 | 中文字幕在线看视频国产中文版 | a在线观看国产 | 人人狠狠综合久久亚洲婷 | 日韩免费高清在线观看 | www.av在线.com | 黄色一级在线视频 | 久久伊人八月婷婷综合激情 | 在线视频1卡二卡三卡 | 国产精品小视频网站 | 国产精品入口传媒 | 成人在线播放免费观看 | 国产一级不卡视频 | 99r精品视频在线观看 | 色婷婷激情四射 | 欧美a在线看 | 成人一区影院 | 岛国av在线 | 精品久久久久久久久久久久久久久久 | 国产精品青草综合久久久久99 | 亚洲黄色三级 | 国产91精品一区二区 | 久久九九国产视频 | 中文字幕视频 | 日韩18p| av夜夜操 | 国产色小视频 | 天天av资源 | 手机成人在线 | 99久久久国产精品免费观看 | 久久免费电影网 | 亚州av网站 | 国产福利免费看 | 免费瑟瑟网站 | 精品国产免费av | 91完整版在线观看 | 久久婷综合| 日韩在线第一区 | 99热九九这里只有精品10 | 99在线观看 | 麻豆影视在线播放 | 久久成年人网站 | 综合色站导航 | 在线电影 你懂得 | 狠狠干2018| 肉色欧美久久久久久久免费看 | 久久久蜜桃一区二区 | 亚洲少妇激情 | 中文字幕在线影视资源 | 在线免费观看黄色大片 | 久草国产在线观看 | www.久久免费视频 | 日韩欧美一区二区不卡 | 色五婷婷| 亚洲精品动漫在线 | 91禁看片| 欧美精品一区二区在线观看 | 成人三级网址 | 日韩系列在线 | 久久成人在线视频 | 成人黄色小说网 | 亚洲成a人片77777kkkk1在线观看 | 精品国产免费观看 | 精品一二三四五区 | 国产日韩中文字幕 | 国内丰满少妇猛烈精品播放 | 国产小视频在线免费观看视频 | 91精品久久久久 | 色婷婷五| 丁香视频在线观看 | 九九热免费在线观看 | 狠狠插狠狠干 | 日日夜夜精品网站 | 精品毛片一区二区免费看 | 天天干夜夜| av不卡免费看 | 在线观看免费一区 | 久久久五月天 | 亚洲国产精品久久久久 | 欧美亚洲三级 | av中文字幕亚洲 | 日韩三级中文字幕 | 日韩一二三区不卡 | 久爱综合 | 伊人黄色网 | 女女av在线 | 香蕉网站在线观看 | 男女日麻批| 日韩丝袜视频 | 在线你懂的视频 | 欧美地下肉体性派对 | 蜜臀av夜夜澡人人爽人人 | 91亚洲成人 | 伊人资源站 | 久久综合久久综合九色 | 亚洲免费国产视频 | 九九热精品视频在线观看 | av高清不卡| 96久久精品| 一级片色播影院 | 精品在线观看视频 | 亚洲人成网站精品片在线观看 | 91免费看片黄 | 免费视频久久久久久久 | 91久久人澡人人添人人爽欧美 | 人人艹人人| 综合网欧美| 日韩在线观看视频免费 | 日本最新一区二区三区 | a在线免费 | 欧美国产日韩一区二区三区 | 四虎在线观看视频 | 午夜 免费 | 欧美成年网站 | 91毛片视频| 九九精品久久 | 亚洲日韩中文字幕在线播放 | 91麻豆产精品久久久久久 | 国产精品1区2区在线观看 | 麻豆免费在线视频 | 欧美一区二区视频97 | 国产亚洲va综合人人澡精品 | 久久久免费看 | 天天躁日日躁狠狠 | 中中文字幕av在线 | 91精品久久久久久久99蜜桃 | 久久久久亚洲国产精品 | 毛片网站免费 | 国内精品久久久久久久97牛牛 | 久久久影院一区二区三区 | 日韩在线视频观看 | 在线小视频你懂得 | 国产精品午夜8888 | 久久不射电影院 | 中文字幕在线影院 | 天堂在线一区二区 | 在线视频 一区二区 | 亚洲涩涩网| 日韩一级网站 | 人人爽久久久噜噜噜电影 | 久久另类小说 | 在线观看网站av | 国产香蕉97碰碰碰视频在线观看 | 婷婷在线不卡 | av中文天堂 | 久久国产精品免费看 | 国产精品久久艹 | 中文字幕免费国产精品 | 91av九色| 91精品国产91久久久久久三级 | 99成人免费视频 | 欧美日韩超碰 | 成人国产精品久久久久久亚洲 | 久久免费美女视频 | 免费在线观看av网址 | 五月婷网站 | 久久久久色 | 五月婷婷另类国产 | 日韩在线观看小视频 | 黄色小说免费观看 | 探花视频在线版播放免费观看 | a色视频 | 欧美少妇bbwhd | 国产精品一区二区三区四区在线观看 | 狠狠干天天色 | 国产精品免费观看网站 | 草久在线播放 | 欧美最猛性xxxxx亚洲精品 | 亚洲精品五月天 | 亚洲一区二区三区四区精品 | 国产精品成人自产拍在线观看 | 久久免费电影网 | 五月天激情综合 | 精品在线视频一区二区三区 | 亚洲欧美视频 | 午夜久久久久久久久久影院 | 国产麻豆传媒 | 成人小视频在线观看免费 | 中文字幕 国产 一区 | 久久久久久久久久免费 | 91在线视频在线 | 国产在线看 | 最新一区二区三区 | 九九免费观看视频 | 久久久蜜桃| 国产区欧美 | 最新国产精品久久精品 | 国产精品毛片一区二区三区 | 亚洲v欧美v国产v在线观看 | 十八岁以下禁止观看的1000个网站 | 在线看国产日韩 | 干干操操| 久久黄色网址 | 午夜精品久久久99热福利 | 免费午夜视频在线观看 | 国产精品激情在线观看 | 一区二区三区在线免费观看视频 | 成人免费观看大片 | 欧美色综合天天久久综合精品 | 亚洲国产精品推荐 | 91视频免费看网站 | 国产精品永久在线 | 99久久久国产精品美女 | 精品在线你懂的 | 久久国产精品免费看 | 99免费精品 | 四虎国产精品免费观看视频优播 | 麻花豆传媒mv在线观看 | 亚洲精品在线免费播放 | 天天干夜夜夜 | 视频一区在线播放 | 日韩欧美黄色网址 | 九九热精品在线 | 久黄色| 午夜色站 | 国产精品久久久久久69 | 黄色成人91 | 在线观看中文字幕2021 | 免费视频一级片 | 人人舔人人舔 | 99视频久| 久久综合中文字幕 | 国产 欧美 在线 | 欧美亚洲另类在线视频 | 精品黄色在线观看 | 蜜臀av性久久久久av蜜臀三区 | 久草在线综合网 | 成人av在线直播 | 成人av在线直播 | 免费看黄在线 | 色就干| 欧美一级特黄aaaaaa大片在线观看 | 亚洲精品456在线播放乱码 | 四虎在线免费观看视频 | 五月视频 | 欧美精品乱码久久久久 | 天天射天天舔天天干 | 超碰97人| 91福利国产在线观看 | 青青网视频| 99久久久国产精品 | 久久综合久久综合这里只有精品 | 亚洲人av免费网站 | 午夜美女影院 | 日韩亚洲精品电影 | 91色视频 | 91在线视频免费91 | 久久久久久中文字幕 | 狠狠狠操 | 日本久久91 | 高清av免费一区中文字幕 | 91视频在线国产 | 国产精品理论在线观看 | 国产99久久久国产精品免费二区 | 五月综合久久 | 91精品国产自产在线观看永久 | 日韩欧美一区二区三区在线 | 国产一级精品绿帽视频 | 99热只有精品在线观看 | 91香蕉视频在线下载 | 天天干夜夜| 在线免费观看黄色大片 | 国产亚洲综合性久久久影院 | 亚洲欧美综合精品久久成人 | 日韩精品在线视频免费观看 | 日韩在线观看视频一区二区三区 | 国产精品久久久久久久妇 | 久久精品99国产国产 | 日本在线观看一区二区三区 | 成人一级 | sm免费xx网站 | 美女免费黄网站 | 久久久一本精品99久久精品 | 四虎国产精品永久在线国在线 | 色在线最新 | 日韩三级免费观看 | 欧美性久久久久久 | 在线观看免费av网站 | av片免费播放 | 四虎影视精品 | 四虎影视精品永久在线观看 | 日韩黄视频 | 91精品国产自产在线观看永久 | 色停停五月天 | 久久经典国产视频 | 久久影院中文字幕 | 日本中文字幕观看 | 亚洲视频精品在线 | 日本在线h | 国产美女被啪进深处喷白浆视频 | 国产精品亚洲人在线观看 | 九色91av | 国产码电影 | 九九九国产 | 久久久久欧美精品 | 久久精品综合网 | 日本黄色免费在线 | 欧美日韩中文在线 | 日韩欧美中文 | 日韩久久在线 | 国产精品成人一区二区 | 西西4444www大胆无视频 | 国产精品网址在线观看 | 免费视频你懂得 | 九九久久婷婷 | 91成人免费电影 | 中文字幕乱码在线播放 | 色老板在线 | 少妇精品久久久一区二区免费 | 国产精品区一区 | 免费在线观看日韩视频 | 国产精品美女www爽爽爽视频 | 精品国产乱码久久久久久浪潮 | 国产一区二区免费 | 日韩性片 | 亚洲精品国内 | 懂色av懂色av粉嫩av分享吧 | 日本黄色免费大片 | 日韩色综合网 | 在线 精品 国产 | 国产亚洲精品久久久久久 | 亚洲a免费 | 久久少妇免费视频 | av在线等| 亚洲综合色丁香婷婷六月图片 | 国产精品久久久久久久妇 | 中文字幕乱在线伦视频中文字幕乱码在线 | 久久免费在线视频 | 亚洲一区二区精品视频 | av韩国在线 | 91精品国产成人观看 | 国内丰满少妇猛烈精品播 | 91久久奴性调教 | 国产中的精品av小宝探花 | 日韩免费三级 | 日韩精品视频免费看 | 国产精品乱码高清在线看 | 日韩欧美一级二级 | 成人福利在线播放 | 国产91全国探花系列在线播放 | 五月激情姐姐 | 日本二区三区在线 | 99免费看片 | 成人av高清在线 | 97超级碰碰 | 国产黑丝一区二区三区 | 国产第一页在线观看 | 亚洲视频1| 一区二区三区动漫 | 色a综合 | 国产三级久久久 | 精品久久久国产 | 国产高清一级 | 91香蕉视频黄色 | 日韩av网页 | 久久刺激视频 | 黄网站色视频免费观看 | 亚洲精品久久久久中文字幕二区 | 在线中文字母电影观看 | 手机av电影在线观看 | 天天爽网站 | 日韩黄在线观看 | 色94色欧美| 一本一本久久a久久精品牛牛影视 | 久久理论电影网 | 免费国产视频 | 国产午夜精品一区二区三区 | 中文字幕大全 | 国产精品美女网站 | 久久精品人人做人人综合老师 | 国产亚洲一区二区在线观看 | 久久一区二区三区超碰国产精品 | 国产中文伊人 | 欧美日韩视频在线一区 | 久久久国产精品一区二区中文 | 久久久www | 欧美大香线蕉线伊人久久 | 国产色小视频 | 日韩中文字幕免费在线观看 | 亚洲欧美日韩精品久久奇米一区 | 久草免费在线观看视频 | 精品一区二三区 | 亚洲精品国产综合99久久夜夜嗨 | 欧美成人精品欧美一级乱黄 | 日日夜夜天天综合 | 欧美日韩久久不卡 | 69国产精品成人在线播放 | 欧美va日韩va | 婷婷激情影院 | 色一级片 | 久久精品高清视频 | 去干成人网 | 国产日本在线播放 | 午夜12点 | 久久久影院官网 | 美女久久一区 | 中文在线字幕观看电影 | 亚洲欧美偷拍另类 | 成人av电影网址 | 亚洲高清av | 999久久久久久久久 69av视频在线观看 | 97碰在线视频 | 最近中文字幕在线 | 成人午夜黄色影院 | 美女视频黄免费 | 欧美夫妻性生活电影 | 在线观看国产www | av电影在线免费 | 免费日韩av电影 | 国产一区二区三区高清播放 |