精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入理解gorm是如何和數(shù)據(jù)庫(kù)建立連接的

開(kāi)發(fā) 前端
在gorm.Open函數(shù)中,第一個(gè)參數(shù)是Dialector類(lèi)型的參數(shù),這是一個(gè)接口類(lèi)型。也就是說(shuō)只要實(shí)現(xiàn)了該接口,就能作為一個(gè)Dialector。這也就是gorm能夠針對(duì)很多數(shù)據(jù)庫(kù)進(jìn)行操作的原因。

大家好,我是漁夫子。

本期和大家一起學(xué)習(xí)下gorm是如何和數(shù)據(jù)庫(kù)建立連接的。

一、gorm.Open

通常情況下,我們是通過(guò)gorm.Open函數(shù)就能在應(yīng)用層和數(shù)據(jù)建立連接。如下:

import (
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)

func main() {
  dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

在該代碼片段中,我們傳入了數(shù)據(jù)庫(kù)的用戶(hù)名、密碼、地址以及數(shù)據(jù)庫(kù)和數(shù)據(jù)庫(kù)對(duì)應(yīng)的配置。然后通過(guò)gorm.Open函數(shù)就和數(shù)據(jù)庫(kù)建立連接了,gorm.Open函數(shù)返回的是一個(gè)gorm.DB對(duì)象。如下:

// DB GORM DB definition
type DB struct {
 *Config
 Error        error
 RowsAffected int64
 Statement    *Statement
 clone        int
}

在該數(shù)據(jù)結(jié)構(gòu)中并沒(méi)有和數(shù)據(jù)庫(kù)連接相關(guān)的字段,那gorm.Open到底是如何和mysql數(shù)據(jù)庫(kù)建立連接的呢?我們繼續(xù)深入gorm.Open函數(shù)和mysql.Open函數(shù)的詳細(xì)內(nèi)容。

二、gorm.Open函數(shù)

在gorm.Open函數(shù)中,傳入的參數(shù)是一個(gè)Dialector?接口類(lèi)型的dialector變量。我們看到會(huì)將傳入的Dialector變量賦值給配置config.Dialector,如下:

config.Dialector = dialector

然后,又通過(guò)config.Dialector的Initialize函數(shù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行了初始化。如下:

err = config.Dialector.Initialize(db)

那么,Dialector是什么呢?Dialector是通過(guò)gorm.Open函數(shù)的第一個(gè)參數(shù)傳進(jìn)來(lái)的。我們看具體的是什么。

三、Dialector參數(shù)

在gorm.Open函數(shù)中,第一個(gè)參數(shù)是Dialector類(lèi)型的參數(shù),這是一個(gè)接口類(lèi)型。也就是說(shuō)只要實(shí)現(xiàn)了該接口,就能作為一個(gè)Dialector。這也就是gorm能夠針對(duì)很多數(shù)據(jù)庫(kù)進(jìn)行操作的原因。比如MySQL、ClickHouse等。Dialector接口類(lèi)型定義如下:

// Dialector GORM database dialector
type Dialector interface {
 Name() string
 Initialize(*DB) error
 Migrator(db *DB) Migrator
 DataTypeOf(*schema.Field) string
 DefaultValueOf(*schema.Field) clause.Expression
 BindVarTo(writer clause.Writer, stmt *Statement, v interface{})
 QuoteTo(clause.Writer, string)
 Explain(sql string, vars ...interface{}) string
}

具體到mysql的數(shù)據(jù)庫(kù),我們看到是通過(guò)gorm.io/driver/mysql?庫(kù)的Open函數(shù)來(lái)初始化的。我們看下mysql.Open函數(shù)的實(shí)現(xiàn),如下:

func Open(dsn string) gorm.Dialector {
 dsnConf, _ := mysql.ParseDSN(dsn)
 return &Dialector{Config: &Config{DSN: dsn, DSNConfig: dsnConf}}
}

該函數(shù)接收一個(gè)dsn的字符串,也就是第一節(jié)中我們提供的和數(shù)據(jù)庫(kù)相關(guān)的賬號(hào)密碼等連接數(shù)據(jù)的信息。然后,返回的是mysql驅(qū)動(dòng)包中的Dialector對(duì)象。該對(duì)象包含了相關(guān)的配置。

然后,是在gorm.Open函數(shù)中,調(diào)用了Dialector的Initialize?函數(shù)。我們看下該函數(shù)中和數(shù)據(jù)庫(kù)連接相關(guān)的邏輯。

func (dialector Dialector) Initialize(db *gorm.DB) (err error) {
 if dialector.DriverName == "" {
  dialector.DriverName = "mysql"
 }

 if dialector.DefaultDatetimePrecision == nil {
  dialector.DefaultDatetimePrecision = &defaultDatetimePrecision
 }

 if dialector.Conn != nil {
  db.ConnPool = dialector.Conn
 } else {
  db.ConnPool, err = sql.Open(dialector.DriverName, dialector.DSN)
  if err != nil {
   return err
  }
 }
    // 省略其他代碼
}

大家看到,在第13行的地方,是通過(guò)sql.Open函數(shù)來(lái)進(jìn)行具體的和數(shù)據(jù)庫(kù)進(jìn)行連接的。然后返回的對(duì)象是sql.DB類(lèi)型,大家注意,這里的sql.DB類(lèi)型是go標(biāo)準(zhǔn)庫(kù)中的DB,而非gorm庫(kù)中的DB。返回的sql.DB對(duì)象賦值給了gorm中DB對(duì)象中的ConnPool。

同時(shí),在gorm.Open函數(shù)中,還將db.ConnPool對(duì)象賦值給了db.Statement.ConnPool對(duì)象。到這里是不是gorm.DB結(jié)構(gòu)體中的字段就和數(shù)據(jù)庫(kù)的具體連接關(guān)聯(lián)起來(lái)。

接下來(lái),我們?cè)倏纯磗ql.Open函數(shù)是如何和數(shù)據(jù)庫(kù)建立連接的。

四、sql.Open函數(shù)

先看sql.Open函數(shù)的源代碼:

func Open(driverName, dataSourceName string) (*DB, error) {
 driversMu.RLock()
 driveri, ok := drivers[driverName]
 driversMu.RUnlock()
 if !ok {
  return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
 }

 if driverCtx, ok := driveri.(driver.DriverContext); ok {
  connector, err := driverCtx.OpenConnector(dataSourceName)
  if err != nil {
   return nil, err
  }
  return OpenDB(connector), nil
 }

 return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
}

我們先簡(jiǎn)單分析下上述代碼。在第3行處,從drivers中獲取對(duì)應(yīng)的驅(qū)動(dòng)名稱(chēng)的具體驅(qū)動(dòng)對(duì)象。這里的driverName是mysql。然后從第9行到第14行是執(zhí)行具體驅(qū)動(dòng)程序的連接函數(shù)。

首先,我們先看從drivers中根據(jù)驅(qū)動(dòng)名稱(chēng)mysql獲取驅(qū)動(dòng)對(duì)象的邏輯。drivers是標(biāo)準(zhǔn)庫(kù)sql中的一個(gè)map類(lèi)型,如下:

drivers   = make(map[string]driver.Driver)

該變量是通過(guò)sql包中的Register函數(shù)進(jìn)行注冊(cè)的:

func Register(name string, driver driver.Driver) {
 driversMu.Lock()
 defer driversMu.Unlock()
 if driver == nil {
  panic("sql: Register driver is nil")
 }
 if _, dup := drivers[name]; dup {
  panic("sql: Register called twice for driver " + name)
 }
 drivers[name] = driver
}

該函數(shù)又是在哪里進(jìn)行調(diào)用的呢?我們?cè)倩卣{(diào)gorm.Open函數(shù)中,第一個(gè)參數(shù)調(diào)用的是mysql.Open函數(shù)。也就是說(shuō)引入了庫(kù)gorm.io/driver/mysql?,在該庫(kù)中,我們看到又引入了github.com/go-sql-driver/mysql?庫(kù)。該庫(kù)中有一個(gè)init方法,如下:

func init() {
 sql.Register("mysql", &MySQLDriver{})
}

原來(lái),這里調(diào)用了標(biāo)準(zhǔn)庫(kù)sql中的Register函數(shù),將“mysql”和對(duì)應(yīng)的驅(qū)動(dòng)對(duì)象MySQLDriver進(jìn)行了注冊(cè)關(guān)聯(lián)。

我們?cè)俜祷貋?lái)看sql.Open函數(shù)的具體實(shí)現(xiàn)。那這里就繼續(xù)調(diào)用MySQLDriver的OpenConnector方法。我們看下該方法的實(shí)現(xiàn)如下:

// OpenConnector implements driver.DriverContext.
func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) {
 cfg, err := ParseDSN(dsn)
 if err != nil {
  return nil, err
 }
 return &connector{
  cfg: cfg,
 }, nil
}

該函數(shù)首先通過(guò)ParseDSN解析dsn字符串中的用戶(hù)名,地址,密碼等配置選項(xiàng)。然后返回一個(gè)connector對(duì)象。該connector對(duì)象就是在sql.Open函數(shù)中執(zhí)行的OpenDB(connector)函數(shù)中的參數(shù)。

我們繼續(xù)看sql.OpenDB函數(shù)的實(shí)現(xiàn),如下:

func OpenDB(c driver.Connector) *DB {
 ctx, cancel := context.WithCancel(context.Background())
 db := &DB{
  connector:    c,
  openerCh:     make(chan struct{}, connectionRequestQueueSize),
  lastPut:      make(map[*driverConn]string),
  connRequests: make(map[uint64]chan connRequest),
  stop:         cancel,
 }

 go db.connectionOpener(ctx)

 return db
}

這里首先構(gòu)建了一個(gè)sql.DB對(duì)象,同時(shí)執(zhí)行了一個(gè)協(xié)程進(jìn)行數(shù)據(jù)庫(kù)的連接:

go db.connectionOpener(ctx)

接著看db.connectionOpener函數(shù)的實(shí)現(xiàn),如下:

// Runs in a separate goroutine, opens new connections when requested.
func (db *DB) connectionOpener(ctx context.Context) {
 for {
  select {
  case <-ctx.Done():
   return
  case <-db.openerCh:
   db.openNewConnection(ctx)
  }
 }
}

這里,有一個(gè)db.openNewConnection函數(shù),根據(jù)名字可知是打開(kāi)新的連接。其實(shí)現(xiàn)如下:

// Open one new connection
func (db *DB) openNewConnection(ctx context.Context) {

 ci, err := db.connector.Connect(ctx)
    // ...省略代碼

 dc := &driverConn{
  db:         db,
  createdAt:  nowFunc(),
  returnedAt: nowFunc(),
  ci:         ci,
 }
 if db.putConnDBLocked(dc, err) {
  db.addDepLocked(dc, dc)
 } else {
  db.numOpen--
  ci.Close()
 }
}

這里我們看到有一個(gè)db.connector.Connect函數(shù),connector就是github.com/go-sql-driver/mysql?庫(kù)中的connector對(duì)象。我們回到該庫(kù),查看其Connect函數(shù)的實(shí)現(xiàn):

// Connect implements driver.Connector interface.
// Connect returns a connection to the database.
func (c *connector) Connect(ctx context.Context) (driver.Conn, error) {
 var err error

 // New mysqlConn
 mc := &mysqlConn{
  maxAllowedPacket: maxPacketSize,
  maxWriteSize:     maxPacketSize - 1,
  closech:          make(chan struct{}),
  cfg:              c.cfg,
 }
 mc.parseTime = mc.cfg.ParseTime

 // Connect to Server
 dialsLock.RLock()
 dial, ok := dials[mc.cfg.Net]
 dialsLock.RUnlock()
 if ok {
     //...省略代碼
 } else {
  nd := net.Dialer{Timeout: mc.cfg.Timeout}
  mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
 }

 // Enable TCP Keepalives on TCP connections
 if tc, ok := mc.netConn.(*net.TCPConn); ok {
  if err := tc.SetKeepAlive(true); err != nil {
            //...省略代碼
  }
 }

 mc.buf = newBuffer(mc.netConn)
 //...

 // Reading Handshake Initialization Packet
 authData, plugin, err := mc.readHandshakePacket()
 if err != nil {
  mc.cleanup()
  return nil, err
 }


 // Send Client Authentication Packet
 authResp, err := mc.auth(authData, plugin)

 if err = mc.writeHandshakeResponsePacket(authResp, plugin); err != nil {
  mc.cleanup()
  return nil, err
 }

 // Handle response to auth packet, switch methods if possible
 if err = mc.handleAuthResult(authData, plugin); err != nil {
  mc.cleanup()
  return nil, err
 }

 return mc, nil
}

這里我們主要看第22到23行,這里進(jìn)行了實(shí)際的撥號(hào)操作,也就是和數(shù)據(jù)庫(kù)真正的建立了連接。再看第27行,斷言是一個(gè)TCP連接。第37行,進(jìn)行了握手處理;第45行,進(jìn)行了認(rèn)證處理。最終返回了一個(gè)mysqlConn對(duì)象。該mysqlConn結(jié)構(gòu)體中包含字段如下:

type mysqlConn struct {
 buf              buffer
 netConn          net.Conn
 rawConn          net.Conn // underlying connection when netConn is TLS connection.
    // ...
}

其中,netConn就是和數(shù)據(jù)庫(kù)建立的TCP的連接。

五、從mysql到gorm.DB

我們?cè)倏偨Y(jié)下上述和mysql相關(guān)的各個(gè)對(duì)象之間的關(guān)聯(lián)關(guān)系。從mysql開(kāi)始逆向推導(dǎo)。如下:圖片

也就是說(shuō),我們?cè)谑褂胓orm進(jìn)行數(shù)據(jù)庫(kù)操作的時(shí)候,最終都是從gorm.Statement.ConnPool中獲取的數(shù)據(jù)庫(kù)連接來(lái)具體執(zhí)行sql語(yǔ)句的。

好了,今天gorm是如何和mysql建立連接的過(guò)程就跟大家分享到這里。

責(zé)任編輯:武曉燕 來(lái)源: Go學(xué)堂
相關(guān)推薦

2023-08-24 08:47:38

2023-10-08 08:11:54

2024-12-02 11:39:30

2016-12-08 15:36:59

HashMap數(shù)據(jù)結(jié)構(gòu)hash函數(shù)

2020-07-21 08:26:08

SpringSecurity過(guò)濾器

2010-06-01 15:25:27

JavaCLASSPATH

2012-11-22 10:11:16

LispLisp教程

2024-10-21 08:08:56

2019-09-16 08:32:59

遞歸算法編程

2009-09-25 09:14:35

Hibernate日志

2021-02-17 11:25:33

前端JavaScriptthis

2023-10-19 11:12:15

Netty代碼

2013-09-22 14:57:19

AtWood

2017-08-15 13:05:58

Serverless架構(gòu)開(kāi)發(fā)運(yùn)維

2025-05-06 00:43:00

MySQL日志文件MIXED 3

2020-09-23 10:00:26

Redis數(shù)據(jù)庫(kù)命令

2017-01-10 08:48:21

2019-06-25 10:32:19

UDP編程通信

2024-02-21 21:14:20

編程語(yǔ)言開(kāi)發(fā)Golang

2025-06-05 05:51:33

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲国产高清一区| 成人免费网站观看| 在线亚洲国产精品网站| 欧美一区二区女人| 日韩视频专区| 中文 欧美 日韩| 久久中文字幕二区| 欧美一区二区播放| 男人天堂av片| 欧美日韩免费做爰大片| 日韩二区三区四区| 日韩视频一区在线| 伦理一区二区| 亚洲人成网站影音先锋播放| 91精品久久久久久久久久另类 | 日韩一级片免费视频| 成人午夜视频一区二区播放| 夜夜夜久久久| 综合国产在线观看| 久久国产免费视频| 户外露出一区二区三区| 亚洲视频精选在线| 激情小说综合网| 日韩国产成人在线| 91精品国产91久久久久久黑人| 精品日韩av一区二区| 国产成人无码av在线播放dvd| 麻豆视频在线免费观看| 国产91综合网| 国产精品美女网站| 国产一级淫片免费| 欧美亚洲在线日韩| 精品国产一区二区三区久久久蜜月| 伊人亚洲福利一区二区三区| 五月综合激情日本mⅴ| 国产精品极品在线| 久久久久久激情| 欧美日韩一二三四| 亚洲国产毛片完整版| 亚洲天堂国产视频| 蜜桃视频m3u8在线观看| 亚洲视频在线一区二区| 久久久水蜜桃| 精品久久国产视频| 视频一区免费在线观看| 欧美成人免费全部| 亚洲不卡的av| 蜜乳av综合| 精品福利视频一区二区三区| 黄色手机在线视频| 夜鲁夜鲁夜鲁视频在线播放| 一区二区三区日韩在线观看| 亚洲一区二区三区欧美| 日韩欧美电影在线观看| 国产成人在线影院| 国产欧亚日韩视频| 草莓视频18免费观看| 亚洲深夜激情| 欧美激情久久久久久| 中文字幕观看av| 不卡中文字幕| 精品播放一区二区| 国产精品91av| avtt久久| 欧美精品第1页| 亚洲老女人av| 51一区二区三区| 欧美性xxxxx极品娇小| 免费人成自慰网站| 青春草视频在线观看| 中文字幕综合网| 一区二区国产日产| 色久视频在线播放| 99久久国产免费看| 九色视频成人porny| 欧美 日韩 中文字幕| 成人一级视频在线观看| a级国产乱理论片在线观看99| 国产毛片一区二区三区va在线| 国产偷自视频区视频一区二区| 欧美激情伊人电影| 国产亚洲欧美精品久久久www | 91人妻一区二区三区| 青青久久精品| 欧美一区二区免费观在线| 岛国毛片在线播放| 亚洲精品555| 羞羞污视频在线观看| 91在线国产观看| 久久精品中文字幕一区二区三区 | 色婷婷狠狠综合| 精品无码一区二区三区在线| gogo高清在线播放免费| 姬川优奈aav一区二区| 成人免费在线小视频| 超碰aⅴ人人做人人爽欧美| 欧美性猛交丰臀xxxxx网站| 韩国一区二区av| 国产综合色在线观看| 欧美日韩国产成人在线91| www.se五月| 成人日韩视频| 欧美一区二区福利在线| 日韩女优在线视频| 猛男gaygay欧美视频| 一区二区三区天堂av| 亚洲区一区二区三| 激情丁香综合| 国产91在线高潮白浆在线观看| 日本黄色中文字幕| 国产真实乱子伦精品视频| 成人动漫网站在线观看| www.com在线观看| 99麻豆久久久国产精品免费| 日韩欧美激情一区二区| 午夜成年人在线免费视频| 色综合亚洲欧洲| 亚洲午夜激情影院| 欧美精品黑人猛交高潮| 色8久久影院午夜场| 在线观看成人小视频| 亚洲色图欧美自拍| 妖精视频一区二区三区| 美女性感视频久久久| 亚洲欧美综合自拍| 精品一区二区在线播放| 国外成人在线视频网站| 经典三级在线| 一区二区理论电影在线观看| 欧美极品欧美精品欧美图片| 伊人久久大香| 日韩精品在线免费| 内射一区二区三区| 久久久xxx| 超碰97网站| 在线免费黄色| 欧美色图在线视频| 91成人在线观看喷潮蘑菇| 国产精品羞羞答答在线观看 | 中文字幕日韩综合| 台湾亚洲精品一区二区tv| 久久精品久久久久久| 伊人中文字幕在线观看| 高清在线不卡av| 人人妻人人澡人人爽精品欧美一区| 樱花草涩涩www在线播放| 欧美人xxxx| 国产ts在线播放| 亚洲精品婷婷| 99porn视频在线| 日本不卡不卡| 欧美日韩日本视频| 亚洲人成人无码网www国产 | 国产精彩视频在线观看| 激情综合网av| 亚洲黄色成人久久久| av资源亚洲| 亚洲国产欧美久久| 激情五月婷婷小说| 国产在线视频精品一区| 亚洲一区二区四区| 日本一区二区三区视频在线| 精品亚洲va在线va天堂资源站| 天堂资源在线播放| 成人综合婷婷国产精品久久| 欧美少妇一区二区三区| 91成人福利社区| 精品国产一区二区三区久久久| 一级一片免费看| 久久久欧美精品sm网站| 久久久久狠狠高潮亚洲精品| 精品亚洲自拍| 68精品国产免费久久久久久婷婷| 丰满熟妇人妻中文字幕| 亚洲永久免费视频| 久久国产免费视频| 夜久久久久久| 蜜桃av噜噜一区二区三| 亚洲精品永久免费视频| 亚洲免费一级电影| 无码人妻精品一区二| 国产片一区二区| 天天干天天综合| 欧美丰满老妇| 91视频免费在线| 日韩123区| 亚洲电影成人av99爱色| 免费一级片视频| 成人免费高清视频在线观看| 欧美成人精品免费| 婷婷综合电影| 国产精品精品一区二区三区午夜版| 国产视频第一页在线观看| 在线视频一区二区三| 91免费在线看片| 国产在线日韩欧美| 东北少妇不带套对白| 亚洲人成网77777色在线播放| 国产不卡在线观看| 黄色片免费在线观看| 91精品国产综合久久精品图片 | 俺去了亚洲欧美日韩| 99草在线视频| 天天亚洲美女在线视频| 日本少妇xxxxx| 国产精品一区二区久久不卡| 日韩欧美一区二| 亚洲精品国产setv| 成人女保姆的销魂服务| 91视频欧美| 中文字幕欧美在线| 亚洲精品一级片| 日本精品视频一区二区三区| 波多野结衣欲乱| 成人sese在线| 日本特黄a级片| 伊人精品在线| 一区不卡字幕| 亚洲小说图片| 亚洲综合一区二区不卡| ****av在线网毛片| 丝袜情趣国产精品| 亚洲色图欧美视频| 91麻豆精品91久久久久同性| 亚洲 欧美 日韩 综合| 亚洲天天做日日做天天谢日日欢| 乱码一区二区三区| 日本女优在线视频一区二区| av女优在线播放| 天天综合一区| 欧美日韩电影一区二区| 日韩在线亚洲| 国产精品一区二区性色av| 91福利区在线观看| 久久亚洲私人国产精品va| 青青国产在线| 欧美精品一区二区三区蜜桃视频 | 国产精品爱久久久久久久| 福利在线导航136| 久久精品人人做人人爽| 国产黄色片在线播放| 精品亚洲国产视频| 欧美 日韩 国产 成人 在线| 欧美一区二区视频在线观看| 波多野结衣视频在线看| 黄色成人av在线| 18精品爽视频在线观看| 亚洲素人一区二区| 国产毛片欧美毛片久久久| 99re视频这里只有精品| 人妻精品久久久久中文字幕69| 麻豆视频一区二区| 日韩中文字幕二区| 亚洲高清网站| 国产av熟女一区二区三区| 天天超碰亚洲| 亚洲一区二区三区加勒比 | 在线观看成人免费视频| 影音先锋在线国产| 亚洲一区自拍偷拍| 外国一级黄色片| 亚洲三级电影网站| 在线看的片片片免费| 亚洲欧洲在线观看av| 欧美成人久久久免费播放| 国产欧美日韩激情| www久久久久久久| 欧美激情中文字幕| 国产一级久久久久毛片精品| 国产欧美在线观看一区| 一级片视频免费看| 中文文精品字幕一区二区| 超碰人人干人人| 国产欧美视频一区二区三区| av黄色在线免费观看| 国产欧美精品在线观看| 2017亚洲天堂| 亚洲欧洲三级电影| 中文字幕av免费在线观看| 一区二区欧美在线观看| 国产网站在线看| 欧美日韩中文字幕| 黄色av网站免费观看| 欧美日韩视频在线一区二区| 97国产精品久久久| 欧美一区二区三区免费视频| 国产又粗又黄又爽视频| 日韩一区二区三区观看| 亚洲经典一区二区三区| 日韩精品久久久久| 人操人视频在线观看| 亚洲男女自偷自拍图片另类| 都市激情在线视频| 久久精品免费播放| 怡红院在线播放| 国产一区二区美女| 性刺激的欧美三级视频| 国产在线精品一区二区不卡了 | 日本xxxxx18| 亚洲作爱视频| 成人高清在线观看视频| 久久综合九色欧美综合狠狠| 中国毛片直接看| 欧美性猛交xxxx黑人| av 一区二区三区| 亚洲日韩中文字幕| 免费影视亚洲| 国产精品美女无圣光视频| 久久动漫网址| 日韩精品手机在线观看| 日本美女视频一区二区| 国产又黄又粗又猛又爽的视频 | 国产精品7777| 欧美久久一二三四区| 精品亚洲综合| 国语自产精品视频在线看一大j8| 日韩午夜视频在线| 日韩av在线电影观看| 国产精品日韩精品欧美精品| 日韩久久久久久久久久久| 国产婷婷一区二区| 五月激情六月丁香| 亚洲第一精品久久忘忧草社区| 午夜视频在线| 国产精品成人va在线观看| 欧美成a人免费观看久久| 91看片淫黄大片91| 精品一区二区国语对白| 亚洲AV无码片久久精品| 亚洲h在线观看| 国产模特av私拍大尺度| 中文字幕亚洲综合久久筱田步美| 伊人久久综合一区二区| 国内一区二区在线视频观看| 在线播放不卡| www日本在线观看| 亚洲欧美国产毛片在线| 国产精品sm调教免费专区| 亚洲片在线观看| 成人性生交大片免费网站| 好吊妞www.84com只有这里才有精品| 国内精品亚洲| 1314成人网| 亚洲美女偷拍久久| 国产富婆一级全黄大片| 不卡av电影在线观看| 国产美女亚洲精品7777| 看一级黄色录像| 国产精品资源在线| 可以直接看的黄色网址| 日韩精品中文字幕在线不卡尤物| av大片在线| 国产精品美女久久久久av福利| 欧美视频官网| 在线观看免费视频黄| 午夜亚洲福利老司机| 亚洲av毛片成人精品| 欧洲成人午夜免费大片| 精品一区二区三| 九九热精品在线播放| 亚洲男人的天堂在线aⅴ视频| 国产高潮在线观看| 久久全球大尺度高清视频| 美女一区二区在线观看| 欧美网站免费观看| 久久久久久久久99精品| 中文字幕免费观看视频| 久久久精品2019中文字幕神马| 精品国产乱码一区二区三区| 国产精品入口芒果| 91蝌蚪国产九色| 国产乱码在线观看| 久久精品视频免费播放| av在线亚洲色图| 黄色a级片免费| 国产精品国产三级国产专播品爱网 | 国内av一区二区| 亚洲成av人片在线观看无码| 蜜桃视频在线观看网站| 国产精品亚发布| 欧美日韩ab| 好吊视频在线观看| 91麻豆精品国产91久久久使用方法| 波多野结衣在线播放| 日韩高清dvd| 国产成人av一区二区三区在线 | 欧美视频一区二区三区四区| 超碰在线观看免费| 久久亚洲综合网| 国产一区欧美二区| 波多野结衣国产| 波霸ol色综合久久| 婷婷成人在线| 久久久精品视频国产| 欧美色欧美亚洲高清在线视频| 免费高清在线观看| 精品一区二区三区日本| 国产一区二区毛片| 久久人人爽人人爽人人片av免费| 欧美二区在线播放|