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

數(shù)據(jù)庫中間件 MyCAT源碼分析 —— PreparedStatement 重新入門

數(shù)據(jù)庫
相信很多同學(xué)在學(xué)習(xí) JDBC 時,都碰到 PreparedStatement 和 Statement。究竟該使用哪個呢?最終很可能是懵里懵懂的看了各種總結(jié),使用 PreparedStatement。那么本文,通過 MyCAT 對 PreparedStatement 的實現(xiàn)對大家能夠重新理解下。

1. 概述

相信很多同學(xué)在學(xué)習(xí) JDBC 時,都碰到 PreparedStatement 和 Statement。究竟該使用哪個呢?最終很可能是懵里懵懂的看了各種總結(jié),使用 PreparedStatement。那么本文,通過 MyCAT 對 PreparedStatement 的實現(xiàn)對大家能夠重新理解下。

本文主要分成兩部分:

  1. JDBC Client 如何實現(xiàn) PreparedStatement。
  2. MyCAT Server 如何處理 PreparedStatement。

😈 Let's Go。

2. JDBC Client 實現(xiàn)

首先,我們來看一段大家最喜歡復(fù)制粘貼之一的代碼,JDBC PreparedStatement 查詢 MySQL 數(shù)據(jù)庫:

  1. public class PreparedStatementDemo { 
  2.  
  3.     public static void main(String[] args) throws ClassNotFoundException, SQLException { 
  4.         // 1. 獲得數(shù)據(jù)庫連接 
  5.         Class.forName("com.mysql.jdbc.Driver"); 
  6.         Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:8066/dbtest?useServerPrepStmts=true""root""123456"); 
  7.  
  8.         // PreparedStatement 
  9.         PreparedStatement ps = conn.prepareStatement("SELECT id, username, password FROM t_user WHERE id = ?"); 
  10.         ps.setLong(1, Math.abs(new Random().nextLong())); 
  11.  
  12.         // execute 
  13.         ps.executeQuery(); 
  14.     } 
  15.  
  16.  

獲取 MySQL 連接時,useServerPrepStmts=true 是非常非常非常重要的參數(shù)。如果不配置,PreparedStatement 實際是個假的 PreparedStatement(新版本默認為 FALSE,據(jù)說部分老版本默認為 TRUE),未開啟服務(wù)端級別的 SQL 預(yù)編譯。

WHY ?來看下 JDBC 里面是怎么實現(xiàn)的。

  1. // com.mysql.jdbc.ConnectionImpl.java 
  2. public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { 
  3.    synchronized (getConnectionMutex()) { 
  4.        checkClosed(); 
  5.  
  6.        PreparedStatement pStmt = null
  7.        boolean canServerPrepare = true
  8.        String nativeSql = getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql) : sql; 
  9.  
  10.        if (this.useServerPreparedStmts && getEmulateUnsupportedPstmts()) { 
  11.            canServerPrepare = canHandleAsServerPreparedStatement(nativeSql); 
  12.        } 
  13.  
  14.        if (this.useServerPreparedStmts && canServerPrepare) { 
  15.            if (this.getCachePreparedStatements()) { // 從緩存中獲取 pStmt 
  16.                synchronized (this.serverSideStatementCache) { 
  17.                    pStmt = (com.mysql.jdbc.ServerPreparedStatement) this.serverSideStatementCache 
  18.                            .remove(makePreparedStatementCacheKey(this.database, sql)); 
  19.  
  20.                    if (pStmt != null) { 
  21.                        ((com.mysql.jdbc.ServerPreparedStatement) pStmt).setClosed(false); 
  22.                        pStmt.clearParameters(); // 清理上次留下的參數(shù) 
  23.                    } 
  24.  
  25.                    if (pStmt == null) { 
  26.                         // .... 省略代碼 :向 Server 提交 SQL 預(yù)編譯。 
  27.                    } 
  28.                } 
  29.            } else { 
  30.                try { 
  31.                    // 向 Server 提交 SQL 預(yù)編譯。 
  32.                    pStmt = ServerPreparedStatement.getInstance(getMultiHostSafeProxy(), nativeSql, this.database, resultSetType, resultSetConcurrency); 
  33.  
  34.                    pStmt.setResultSetType(resultSetType); 
  35.                    pStmt.setResultSetConcurrency(resultSetConcurrency); 
  36.                } catch (SQLException sqlEx) { 
  37.                    // Punt, if necessary 
  38.                    if (getEmulateUnsupportedPstmts()) { 
  39.                        pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false); 
  40.                    } else { 
  41.                        throw sqlEx; 
  42.                    } 
  43.                } 
  44.            } 
  45.        } else { 
  46.            pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false); 
  47.        } 
  48.  
  49.        return pStmt; 
  50.    } 
  51.  
  • 【前者】當(dāng) Client 開啟 useServerPreparedStmts 并且 Server 支持 ServerPrepare,Client 會向 Server 提交 SQL 預(yù)編譯請求。
  1. if (this.useServerPreparedStmts && canServerPrepare) { 
  2.     pStmt = ServerPreparedStatement.getInstance(getMultiHostSafeProxy(), nativeSql, this.database, resultSetType, resultSetConcurrency); 
  3. } 
  • 【后者】當(dāng) Client 未開啟 useServerPreparedStmts 或者 Server 不支持 ServerPrepare,Client 創(chuàng)建 PreparedStatement,不會向 Server 提交 SQL 預(yù)編譯請求。
  1. pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false); 

即使這樣,究竟為什么性能會更好呢?

  • 【前者】返回的 PreparedStatement 對象類是 JDBC42ServerPreparedStatement.java,后續(xù)每次執(zhí)行 SQL 只需將對應(yīng)占位符?對應(yīng)的值提交給 Server即可,減少網(wǎng)絡(luò)傳輸和 SQL 解析開銷。
  • 【后者】返回的 PreparedStatement 對象類是 JDBC42PreparedStatement.java,后續(xù)每次執(zhí)行 SQL 需要將完整的 SQL 提交給 Server,增加了網(wǎng)絡(luò)傳輸和 SQL 解析開銷。

🌚:【前者】性能一定比【后者】好嗎?相信你已經(jīng)有了正確的答案。

3. MyCAT Server 實現(xiàn)

3.1 創(chuàng)建 PreparedStatement

該操作對應(yīng) Client conn.prepareStatement(....)。 

 

 

 

MyCAT 接收到請求后,創(chuàng)建 PreparedStatement,并返回 statementId 等信息。Client 發(fā)起 SQL 執(zhí)行時,需要將 statementId 帶給 MyCAT。核心代碼如下:

  1. // ServerPrepareHandler.java 
  2. @Override 
  3. public void prepare(String sql) { 
  4. LOGGER.debug("use server prepare, sql: " + sql); 
  5.  
  6.    PreparedStatement pstmt = pstmtForSql.get(sql); 
  7.    if (pstmt == null) { // 緩存中獲取 
  8.        // 解析獲取字段個數(shù)和參數(shù)個數(shù) 
  9.        int columnCount = getColumnCount(sql); 
  10.        int paramCount = getParamCount(sql); 
  11.        pstmt = new PreparedStatement(++pstmtId, sql, columnCount, paramCount); 
  12.        pstmtForSql.put(pstmt.getStatement(), pstmt); 
  13.        pstmtForId.put(pstmt.getId(), pstmt); 
  14.    } 
  15.    PreparedStmtResponse.response(pstmt, source); 
  16. // PreparedStmtResponse.java 
  17. public static void response(PreparedStatement pstmt, FrontendConnection c) { 
  18.    byte packetId = 0; 
  19.  
  20.    // write preparedOk packet 
  21.    PreparedOkPacket preparedOk = new PreparedOkPacket(); 
  22.    preparedOk.packetId = ++packetId; 
  23.    preparedOk.statementId = pstmt.getId(); 
  24.    preparedOk.columnsNumber = pstmt.getColumnsNumber(); 
  25.    preparedOk.parametersNumber = pstmt.getParametersNumber(); 
  26.    ByteBuffer buffer = preparedOk.write(c.allocate(), c,true); 
  27.  
  28.    // write parameter field packet 
  29.    int parametersNumber = preparedOk.parametersNumber; 
  30.    if (parametersNumber > 0) { 
  31.        for (int i = 0; i < parametersNumber; i++) { 
  32.            FieldPacket field = new FieldPacket(); 
  33.            field.packetId = ++packetId; 
  34.            buffer = field.write(buffer, c,true); 
  35.        } 
  36.        EOFPacket eof = new EOFPacket(); 
  37.        eof.packetId = ++packetId; 
  38.        buffer = eof.write(buffer, c,true); 
  39.    } 
  40.  
  41.    // write column field packet 
  42.    int columnsNumber = preparedOk.columnsNumber; 
  43.    if (columnsNumber > 0) { 
  44.        for (int i = 0; i < columnsNumber; i++) { 
  45.            FieldPacket field = new FieldPacket(); 
  46.            field.packetId = ++packetId; 
  47.            buffer = field.write(buffer, c,true); 
  48.        } 
  49.        EOFPacket eof = new EOFPacket(); 
  50.        eof.packetId = ++packetId; 
  51.        buffer = eof.write(buffer, c,true); 
  52.    } 
  53.  
  54.    // send buffer 
  55.    c.write(buffer); 
  56.  

每個連接之間,PreparedStatement 不共享,即不同連接,即使 SQL相同,對應(yīng)的 PreparedStatement 不同。

3.2 執(zhí)行 SQL

該操作對應(yīng) Client conn.execute(....)。 

 

 

 

MyCAT 接收到請求后,將 PreparedStatement 使用請求的參數(shù)格式化成可執(zhí)行的 SQL 進行執(zhí)行。偽代碼如下:

  1. String sql = pstmt.sql.format(request.params); 
  2.  
  3. execute(sql);  

核心代碼如下:

  1. // ServerPrepareHandler.java 
  2. @Override 
  3. public void execute(byte[] data) { 
  4.    long pstmtId = ByteUtil.readUB4(data, 5); 
  5.    PreparedStatement pstmt = null
  6.    if ((pstmt = pstmtForId.get(pstmtId)) == null) { 
  7.        source.writeErrMessage(ErrorCode.ER_ERROR_WHEN_EXECUTING_COMMAND, "Unknown pstmtId when executing."); 
  8.    } else { 
  9.        // 參數(shù)讀取 
  10.        ExecutePacket packet = new ExecutePacket(pstmt); 
  11.        try { 
  12.            packet.read(data, source.getCharset()); 
  13.        } catch (UnsupportedEncodingException e) { 
  14.            source.writeErrMessage(ErrorCode.ER_ERROR_WHEN_EXECUTING_COMMAND, e.getMessage()); 
  15.            return
  16.        } 
  17.        BindValue[] bindValues = packet.values
  18.        // 還原sql中的動態(tài)參數(shù)為實際參數(shù)值 
  19.        String sql = prepareStmtBindValue(pstmt, bindValues); 
  20.        // 執(zhí)行sql 
  21.        source.getSession2().setPrepared(true); 
  22.        source.query(sql); 
  23.    } 
  24.  
  25. private String prepareStmtBindValue(PreparedStatement pstmt, BindValue[] bindValues) { 
  26.    String sql = pstmt.getStatement(); 
  27.    int[] paramTypes = pstmt.getParametersType(); 
  28.  
  29.    StringBuilder sb = new StringBuilder(); 
  30.    int idx = 0; 
  31.    for (int i = 0, len = sql.length(); i < len; i++) { 
  32.        char c = sql.charAt(i); 
  33.        if (c != '?') { 
  34.            sb.append(c); 
  35.            continue
  36.        } 
  37.        // 處理占位符? 
  38.        int paramType = paramTypes[idx]; 
  39.        BindValue bindValue = bindValues[idx]; 
  40.        idx++; 
  41.        // 處理字段為空的情況 
  42.        if (bindValue.isNull) { 
  43.            sb.append("NULL"); 
  44.            continue
  45.        } 
  46.        // 非空情況, 根據(jù)字段類型獲取值 
  47.        switch (paramType & 0xff) { 
  48.            case Fields.FIELD_TYPE_TINY: 
  49.                sb.append(String.valueOf(bindValue.byteBinding)); 
  50.                break; 
  51.            case Fields.FIELD_TYPE_SHORT: 
  52.                sb.append(String.valueOf(bindValue.shortBinding)); 
  53.                break; 
  54.            case Fields.FIELD_TYPE_LONG: 
  55.                sb.append(String.valueOf(bindValue.intBinding)); 
  56.                break; 
  57.            // .... 省略非核心代碼 
  58.         } 
  59.    } 
  60.  
  61.    return sb.toString(); 
  62.  

4. 彩蛋

💯 看到此處是不是真愛?!反正我信了。

給老鐵們額外加個🍗。

細心的同學(xué)們可能已經(jīng)注意到 JDBC Client 是支持緩存 PreparedStatement,無需每次都讓 Server 進行創(chuàng)建。

當(dāng)配置 MySQL 數(shù)據(jù)連接 cachePrepStmts=true 時開啟 Client 級別的緩存。But,此處的緩存又和一般的緩存不一樣,是使用 remove 的方式獲得的,并且創(chuàng)建好 PreparedStatement 時也不添加到緩存。那什么時候添加緩存呢?在 pstmt.close() 時,并且pstmt 是通過緩存獲取時,添加到緩存。核心代碼如下:

  1. // ServerPreparedStatement.java 
  2. public void close() throws SQLException { 
  3.    MySQLConnection locallyScopedConn = this.connection
  4.  
  5.    if (locallyScopedConn == null) { 
  6.        return; // already closed 
  7.    } 
  8.  
  9.    synchronized (locallyScopedConn.getConnectionMutex()) { 
  10.        if (this.isCached && isPoolable() && !this.isClosed) { 
  11.            clearParameters(); 
  12.            this.isClosed = true
  13.            this.connection.recachePreparedStatement(this); 
  14.            return
  15.        } 
  16.  
  17.        realClose(truetrue); 
  18.    } 
  19. // ConnectionImpl.java 
  20. public void recachePreparedStatement(ServerPreparedStatement pstmt) throws SQLException { 
  21.    synchronized (getConnectionMutex()) { 
  22.        if (getCachePreparedStatements() && pstmt.isPoolable()) { 
  23.            synchronized (this.serverSideStatementCache) { 
  24.                this.serverSideStatementCache.put(makePreparedStatementCacheKey(pstmt.currentCatalog, pstmt.originalSql), pstmt); 
  25.            } 
  26.        } 
  27.    } 
  28.  

為什么要這么實現(xiàn)?PreparedStatement 是有狀態(tài)的變量,我們會去 setXXX(pos, value),一旦多線程共享,會導(dǎo)致錯亂。 

責(zé)任編輯:龐桂玉 來源: 芋艿V的博客
相關(guān)推薦

2017-07-26 09:41:28

MyCATSQLMongoDB

2017-07-18 17:07:40

數(shù)據(jù)庫 MyCATJoin

2017-12-01 05:04:32

數(shù)據(jù)庫中間件Atlas

2017-11-27 05:36:16

數(shù)據(jù)庫中間件TDDL

2017-11-27 05:06:42

數(shù)據(jù)庫中間件cobar

2018-02-24 19:37:33

Java8數(shù)據(jù)庫中間件

2009-01-20 10:45:55

Oracle數(shù)據(jù)庫中間件

2011-08-10 13:03:58

CJDBC數(shù)據(jù)庫集群

2017-05-23 18:55:05

mysql-proxy數(shù)據(jù)庫架構(gòu)

2017-11-27 06:01:37

數(shù)據(jù)庫中間件中間層

2017-12-01 05:40:56

數(shù)據(jù)庫中間件join

2017-12-11 13:30:49

Go語言數(shù)據(jù)庫中間件

2020-04-10 17:00:33

Mycat分庫分表SpringBoot

2017-11-03 11:02:08

數(shù)據(jù)庫中間件

2017-11-30 08:56:14

數(shù)據(jù)庫中間件架構(gòu)師

2024-12-06 08:29:29

2019-05-13 15:00:14

MySQLMyCat數(shù)據(jù)庫

2021-07-27 05:49:59

MySQL數(shù)據(jù)庫中間件

2020-10-15 08:34:32

數(shù)據(jù)庫中間件漫談

2018-11-07 15:30:19

數(shù)據(jù)庫NewSQLNoSQL
點贊
收藏

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

调教+趴+乳夹+国产+精品| 毛片一区二区三区| 精品国产1区二区| 黄色免费视频大全| 国产最新视频在线| 久久99精品久久只有精品| 久久成年人免费电影| 亚洲精品乱码久久| 成人亚洲视频| 亚洲一区在线观看网站| 欧美精品一区二区三区在线看午夜 | 日韩成人亚洲| 亚洲精品水蜜桃| 成人黄视频免费| 亚洲精品一区二三区| 欧美在线国产| 国产一区二区三区视频| 可以看的av网址| 亚洲wwww| 精品久久久久久久久久久久久久| 亚洲一区在线免费| 五月天丁香视频| 久久99深爱久久99精品| 97成人在线视频| 欧美成人精品一区二区免费看片| 怕怕欧美视频免费大全| 欧美大片免费久久精品三p| 久久久精品麻豆| 黄色污网站在线观看| 综合久久综合久久| 色一情一区二区三区四区| 亚洲国产精品18久久久久久| 久久精品国产网站| 日韩av免费在线| 日本少妇在线观看| 欧美日韩国产高清| 久久精品视频免费播放| 在线观看国产精品一区| 露出调教综合另类| 欧美va亚洲va香蕉在线| 在线视频一二区| 电影亚洲一区| 日本韩国欧美在线| 116极品美女午夜一级| 2018av在线| 一片黄亚洲嫩模| 日本道在线视频| 国产精品va在线观看视色| 国产精品视频yy9299一区| 欧美韩国日本精品一区二区三区| 秋霞网一区二区| 成人污视频在线观看| 91在线免费看片| 亚洲av无码国产精品久久不卡| 精品一区二区三区在线观看 | 成人国产精品久久| 欧美日韩在线播放三区四区| 黑人粗进入欧美aaaaa| 亚洲精品中文字幕| 91久久免费观看| 成人亚洲视频在线观看| 123成人网| 欧美三级视频在线播放| 日本超碰在线观看| 欧美天堂一区二区| 欧美电影在线免费观看| 中文字幕第21页| aaaa欧美| 欧美日韩国产高清一区二区三区 | 日韩精品手机在线观看| 国产三区在线观看| 亚洲综合另类小说| 亚洲熟妇av一区二区三区漫画| 中文字幕在线免费观看视频| 在线亚洲精品福利网址导航| 手机视频在线观看| 亚洲三级电影| 亚洲第一av网站| 成人免费无码大片a毛片| 你微笑时很美电视剧整集高清不卡| 亚洲男人的天堂在线| 精品人妻中文无码av在线| 成人看的视频| 美女扒开尿口让男人操亚洲视频网站| 中文字幕av免费在线观看| 雨宫琴音一区二区在线| 国产激情视频一区| 91激情在线观看| 丁香五精品蜜臀久久久久99网站| 精品伦精品一区二区三区视频| 欧美精品少妇| 亚洲码国产岛国毛片在线| 久久天天东北熟女毛茸茸| 九色porny丨首页入口在线| 91成人在线精品| 巨乳女教师的诱惑| 亚洲区小说区图片区qvod按摩| 综合久久五月天| 国产精品50页| 日韩成人av影视| 99国产超薄肉色丝袜交足的后果| 天堂在线中文网| 国产精品日韩成人| 欧美啪啪免费视频| 亚洲综合视频| 亚洲精品午夜精品| 国产黄在线免费观看| 性一交一乱一区二区洋洋av| 国产有码一区二区| 婷婷综合激情网| 亚洲欧美偷拍三级| 无码日韩人妻精品久久蜜桃| xxxx日韩| 日韩亚洲欧美中文在线| 奇米影视第四色777| 免费成人在线视频观看| 久久国产精品一区二区三区四区 | 亚洲欧美aⅴ...| 国产精品第12页| a看欧美黄色女同性恋| 久久精品国产91精品亚洲| www毛片com| 成人免费观看视频| 国产av不卡一区二区| 日韩不卡免费高清视频| 亚洲国产天堂久久综合网| 国产suv精品一区二区68| 丝瓜av网站精品一区二区| 国产高清精品一区二区| 日本精品在线| 在线日韩一区二区| 久久亚洲AV成人无码国产野外| 欧美日韩一区自拍| 91在线国产电影| 嫩草在线视频| 在线观看欧美日本| 强伦人妻一区二区三区| 在线亚洲欧美| 国产一区二区三区高清视频| 欧美韩日亚洲| 日韩精品一区二区三区在线观看 | 国产精品视频一区国模私拍| 视频一区二区在线播放| 亚洲va在线va天堂| 日本wwwwwww| 国产精品v亚洲精品v日韩精品| 91在线观看免费高清完整版在线观看| 免费人成在线观看播放视频| 欧美性大战久久久久久久| 欧美黄色一级生活片| 久久久久国内| 欧洲一区二区日韩在线视频观看免费| 在线亚洲人成| 亚洲欧美日韩一区二区在线| 色av性av丰满av| 久久久久国产精品人| 欧美激情精品久久久久久小说| 亚洲免费福利一区| 国产精品美乳一区二区免费| 一级毛片视频在线| 欧美一区二区视频在线观看2020 | 无码人妻aⅴ一区二区三区 | 另类小说第一页| 欧美午夜精品一区二区三区电影| 国产精品成人国产乱一区| 国产一级在线| 欧美丰满少妇xxxxx高潮对白| 登山的目的在线| 国产高清一区日本| 欧美二区在线视频| 一呦二呦三呦国产精品| 国产精品h片在线播放| 亚洲欧美视频一区二区| 欧美一区二区三区日韩| 免费毛片一区二区三区| 久久色在线观看| 亚洲一级免费观看| 午夜久久福利| 蜜桃成人免费视频| 日本久久二区| 久久久久这里只有精品| 久久这里精品| 欧美精品久久久久久久多人混战 | 91精品国产综合久久香蕉922| av片在线观看免费| 亚洲精品美女在线| 亚洲天堂手机版| 亚洲精品乱码久久久久久黑人| 国产人妻黑人一区二区三区| 日韩国产精品大片| 国产日韩欧美大片| 欧美男gay| 91精品视频在线免费观看| 678在线观看视频| 最近2019好看的中文字幕免费| www.五月天激情| 欧美日韩一区免费| 男人操女人的视频网站| 久久毛片高清国产| 佐山爱在线视频| 免费日韩视频| 激情六月天婷婷| 国产免费播放一区二区| 成人片在线免费看| 国产经典一区| 国内外成人免费激情在线视频网站 | 精品无码免费视频| 国产欧美1区2区3区| 美女网站视频在线观看| 美女精品自拍一二三四| 老太脱裤子让老头玩xxxxx| 日韩精品第一区| 精品国产综合| 日韩08精品| 国产综合视频在线观看| 日韩影片中文字幕| 性欧美长视频免费观看不卡| www在线免费观看视频| 尤物精品国产第一福利三区| 欧美日韩精品免费观看| 在线三级电影| 中文字幕v亚洲ⅴv天堂| 同心难改在线观看| 欧美成va人片在线观看| 国产孕妇孕交大片孕| 日韩欧美福利视频| 日韩精品成人一区| 一区二区三区在线不卡| 国产精品1区2区3区4区| 久久久不卡网国产精品二区| 三级视频网站在线观看| 国产激情一区二区三区四区 | 久久成人在线观看| 亚洲欧洲av在线| 青青青手机在线视频| 国产三级三级三级精品8ⅰ区| 玖玖爱在线精品视频| 成人妖精视频yjsp地址| 天天干天天曰天天操| 久久成人av少妇免费| 麻豆三级在线观看| 青青草国产精品亚洲专区无| 99视频免费播放| 视频在线观看一区| 久久好看免费视频| 熟女少妇a性色生活片毛片| 久久综合久久综合久久| av网页在线观看| 99久久久精品| 亚洲精品视频大全| 91视频免费看| 右手影院亚洲欧美| 久久久精品天堂| 五月天综合视频| 亚洲国产精品精华液ab| 成人无码精品1区2区3区免费看| 国产精品久久毛片| 黄色a级片在线观看| 亚洲色图19p| 黄色一级片中国| 一级日本不卡的影视| 伊人国产在线观看| 精品人伦一区二区三区蜜桃网站| 国产香蕉视频在线| 色播五月激情综合网| 懂色av蜜臀av粉嫩av分享吧最新章节| 在线这里只有精品| 91福利在线观看视频| 欧美大片顶级少妇| 日韩av资源| 中文字幕亚洲专区| 四虎久久免费| 久久99视频免费| 日本а中文在线天堂| 国产精品1区2区在线观看| 农村妇女一区二区| 国产精品久久久久久久免费大片 | 麻豆国产欧美一区二区三区| 亚洲精品mv在线观看| 成人天堂资源www在线| 粉嫩av蜜桃av蜜臀av| 中文字幕亚洲视频| 久久网一区二区| 欧美日韩美女视频| 一区二区日韩在线观看| 日韩精品一区二区三区视频| 三级在线播放| 久久视频在线直播| 午夜影院在线播放| 国产日韩在线精品av| 久久久久久毛片免费看 | 嫩草在线视频| 97在线视频免费播放| 久久一区二区三区视频| aaa欧美日韩| 午夜精品久久久久99蜜桃最新版| 亚洲一二三四在线| 日本一区二区三区久久| 亚洲精品一区二区三区影院| 国产精品久久一区二区三区不卡| 欧美美女操人视频| 二吊插入一穴一区二区| 99爱精品视频| 欧美日韩在线二区| 日本男女交配视频| 极品少妇xxxx精品少妇偷拍| 日本黄色录像片| 亚洲伦理在线精品| 中文字幕一区二区三区四区免费看| 日韩精品中文字幕一区二区三区| 在线视频自拍| 欧美一级片免费在线| 欧美成人精品一级| 色乱码一区二区三在线看| 国产色综合网| 久久久久久久久久久久国产精品| 国产欧美视频一区二区| 九九视频免费看| 欧美精品国产精品| 91看片在线观看| 国产福利视频一区| 一区二区美女| 亚洲国产精品久久久久婷蜜芽| 国产精品18久久久久久久网站| 在线免费看视频| 色婷婷亚洲婷婷| 性猛交xxxx| 78m国产成人精品视频| 成人资源在线播放| 国内自拍中文字幕| 狠狠色丁香九九婷婷综合五月| 一区二区伦理片| 在线日韩av片| 国模精品一区二区| 青青草成人在线| 三级小说欧洲区亚洲区| 青青草视频在线免费播放| 高清shemale亚洲人妖| 中文字幕影音先锋| 日韩欧美色综合| 性欧美videos高清hd4k| 亚洲一区二区三区视频| 亚洲乱码在线| 香蕉视频xxxx| 一区二区三区四区精品在线视频 | 久久免费视频2| 韩国视频一区二区| 九九精品视频免费| 日韩欧美国产一区二区在线播放| 国产欧美黑人| 99一区二区三区| 精品999日本| 欧美 变态 另类 人妖| 色综合久久中文字幕综合网| 九色在线观看| 国产精品久久久久久亚洲调教| 日韩成人精品一区二区| 国模精品一区二区三区| 国产一区影院| 中文字幕中文字幕在线中心一区| 久久99精品国产麻豆婷婷洗澡| 欧美做爰啪啪xxxⅹ性| 欧美tk—视频vk| 天堂中文最新版在线中文| 免费亚洲精品视频| 裸体一区二区三区| 破处女黄色一级片| 欧美mv和日韩mv国产网站| 国产传媒av在线| 日韩美女一区| 国产在线一区二区综合免费视频| 五月婷婷一区二区| 国产视频亚洲精品| 精品久久福利| 9色porny| 日本一区二区三区视频视频| ,一级淫片a看免费| 久久久久久国产精品| 国产亚洲一区| 年下总裁被打光屁股sp| 一本色道久久综合亚洲91| 黄色成人在线| 久久综合入口| 精品亚洲porn| 成年免费在线观看| 日韩中文字幕亚洲| 第四色中文综合网| 一区二区三区 日韩| 午夜久久电影网| 欧美黑人激情| 久久久av水蜜桃| 狠狠色丁香九九婷婷综合五月| 亚洲免费激情视频| www.亚洲人.com| 日本妇女一区| 黄色a级三级三级三级| 日韩欧美在线网址 | 26uuu国产精品视频| 欧美独立站高清久久| 六十路息与子猛烈交尾|