亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數(shù)據(jù)庫 > PostgreSQL > 正文

Mybatis調用PostgreSQL存儲過程實現(xiàn)數(shù)組入?yún)鬟f

2020-01-31 15:21:54
字體:
來源:轉載
供稿:網(wǎng)友

前言

項目中用到了Mybatis調用PostgreSQL存儲過程(自定義函數(shù))相關操作,由于PostgreSQL自帶數(shù)組類型,所以有一個自定義函數(shù)的入?yún)⒕褪且粋€int數(shù)組,形如:

復制代碼 代碼如下:
CREATE OR REPLACE FUNCTION "public"."func_arr_update"(ids _int4)...

如上所示,參數(shù)是一個int數(shù)組,Mybatis提供了對調用存儲過程的支持,那么PostgreSQL獨有的數(shù)組類型作為存儲過程的參數(shù)又將如何處理呢?其實很簡單,mybatis提供了typeHandlers可以創(chuàng)建一個數(shù)組類型的類型處理器,具體做法為:實現(xiàn) org.apache.ibatis.type.TypeHandler 接口, 或繼承一個很便利的類 org.apache.ibatis.type.BaseTypeHandler, 然后可以選擇性地將它映射到一個 JDBC 類型,先稍作了解,后面再做詳細說明,接下來依舊結合一個示例來看看。

創(chuàng)建自定義函數(shù)

如圖,第一步首先是創(chuàng)建一個用于調用的自定義函數(shù),功能也很簡單,遍歷參數(shù)數(shù)組的每一個元素和t_student表的stuid做比較,若一致,則修改那條記錄的stuname(在其后拼接一段字符串),該自定義函數(shù)的DLL語句如下:

CREATE OR REPLACE FUNCTION "public"."func_arr_update"(ids _int4) RETURNS "pg_catalog"."void" AS $BODY$DECLARE   scount INTEGER;   rownum integer := 1;BEGIN    scount:=array_length(ids,1);    while rownum <= scount LOOP      update t_student set stuname = stuname || ' has been modified. ' where stuid = ids[rownum];      rownum := rownum + 1;  END LOOP;  RETURN;END$BODY$ LANGUAGE 'plpgsql' VOLATILE COST 100;ALTER FUNCTION "public"."func_arr_update"(ids _int4) OWNER TO "postgres";

很簡單,獲取到參數(shù)數(shù)組的長度后開始循環(huán),匹配stuid并更新stuname,直接在數(shù)據(jù)庫調用一下看看結果:

如上圖,可以看到成功修改了stuid為101,102和103的stuname,自定義函數(shù)已經(jīng)沒問題了,接下來就具體看一下如何通過mybatis調用。

調用自定義函數(shù)

mybatis中調用自定義函數(shù)很簡單,Mapper XML文件中的select元素直接提供了屬性支持――statementType,在官方文檔中可以看到:

如上圖,statementType的值默認是PREPARED,也就是說底層默認會使用jdbc的PreparedStatement,而我們都知道jdbc調用存儲過程時需要用CallableStatement,所以在這里我們需要將statementType的值設置為CALLABLE。

mybatis默認的ArrayTypeHandler

調用存儲過程很簡單,那么接下來的問題是如何在mybatis中傳一個數(shù)組參數(shù)到存儲過程中呢?這里就要用到另外一個概念――TypeHandler,這是mybatis提供的自定義類型轉換器,mybatis在預編譯語句對象(PreparedStatement)設置參數(shù)時或是從結果集中取值時都會用類型處理器將獲取的值以合適的方式轉換成Java類型,mybatis默認實現(xiàn)了一部分TypeHandler供我們使用,當我們沒有指定TypeHandler時(大多數(shù)情況都不會指定),mybatis會根據(jù)參數(shù)或者返回結果的不同,默認為我們選擇合適的TypeHandler處理,下面可以通過查看源碼大概看一下默認的TypeHandler,導入源碼后可以在org.apache.ibatis.type包下找到一個TypeHandlerRegistry類,typeHandler正是通過這個類管理的,先看一下它的構造方法:

 public TypeHandlerRegistry() {  register(Boolean.class, new BooleanTypeHandler());  register(boolean.class, new BooleanTypeHandler());  register(JdbcType.BOOLEAN, new BooleanTypeHandler());  register(JdbcType.BIT, new BooleanTypeHandler());  register(Byte.class, new ByteTypeHandler());  register(byte.class, new ByteTypeHandler());  register(JdbcType.TINYINT, new ByteTypeHandler());  register(Short.class, new ShortTypeHandler());  register(short.class, new ShortTypeHandler());  register(JdbcType.SMALLINT, new ShortTypeHandler());  register(Integer.class, new IntegerTypeHandler());  register(int.class, new IntegerTypeHandler());  register(JdbcType.INTEGER, new IntegerTypeHandler());  register(Long.class, new LongTypeHandler());  register(long.class, new LongTypeHandler());  register(Float.class, new FloatTypeHandler());  register(float.class, new FloatTypeHandler());  register(JdbcType.FLOAT, new FloatTypeHandler());  register(Double.class, new DoubleTypeHandler());  register(double.class, new DoubleTypeHandler());  register(JdbcType.DOUBLE, new DoubleTypeHandler());  register(String.class, new StringTypeHandler());  register(String.class, JdbcType.CHAR, new StringTypeHandler());  register(String.class, JdbcType.CLOB, new ClobTypeHandler());  register(String.class, JdbcType.VARCHAR, new StringTypeHandler());  register(String.class, JdbcType.LONGVARCHAR, new ClobTypeHandler());  register(String.class, JdbcType.NVARCHAR, new NStringTypeHandler());  register(String.class, JdbcType.NCHAR, new NStringTypeHandler());  register(String.class, JdbcType.NCLOB, new NClobTypeHandler());  register(JdbcType.CHAR, new StringTypeHandler());  register(JdbcType.VARCHAR, new StringTypeHandler());  register(JdbcType.CLOB, new ClobTypeHandler());  register(JdbcType.LONGVARCHAR, new ClobTypeHandler());  register(JdbcType.NVARCHAR, new NStringTypeHandler());  register(JdbcType.NCHAR, new NStringTypeHandler());  register(JdbcType.NCLOB, new NClobTypeHandler());  register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler());  register(JdbcType.ARRAY, new ArrayTypeHandler());  register(BigInteger.class, new BigIntegerTypeHandler());  register(JdbcType.BIGINT, new LongTypeHandler());  register(BigDecimal.class, new BigDecimalTypeHandler());  register(JdbcType.REAL, new BigDecimalTypeHandler());  register(JdbcType.DECIMAL, new BigDecimalTypeHandler());  register(JdbcType.NUMERIC, new BigDecimalTypeHandler());  register(Byte[].class, new ByteObjectArrayTypeHandler());  register(Byte[].class, JdbcType.BLOB, new BlobByteObjectArrayTypeHandler());  register(Byte[].class, JdbcType.LONGVARBINARY, new BlobByteObjectArrayTypeHandler());  register(byte[].class, new ByteArrayTypeHandler());  register(byte[].class, JdbcType.BLOB, new BlobTypeHandler());  register(byte[].class, JdbcType.LONGVARBINARY, new BlobTypeHandler());  register(JdbcType.LONGVARBINARY, new BlobTypeHandler());  register(JdbcType.BLOB, new BlobTypeHandler());  register(Object.class, UNKNOWN_TYPE_HANDLER);  register(Object.class, JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);  register(JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);  register(Date.class, new DateTypeHandler());  register(Date.class, JdbcType.DATE, new DateOnlyTypeHandler());  register(Date.class, JdbcType.TIME, new TimeOnlyTypeHandler());  register(JdbcType.TIMESTAMP, new DateTypeHandler());  register(JdbcType.DATE, new DateOnlyTypeHandler());  register(JdbcType.TIME, new TimeOnlyTypeHandler());  register(java.sql.Date.class, new SqlDateTypeHandler());  register(java.sql.Time.class, new SqlTimeTypeHandler());  register(java.sql.Timestamp.class, new SqlTimestampTypeHandler());  // issue #273  register(Character.class, new CharacterTypeHandler());  register(char.class, new CharacterTypeHandler()); }

如上所示,這就是全部默認的typeHandler了,注意一下46,47行可以看到默認有一個ArrayTypeHandler,順便看一下它的源碼:

/* *  Copyright 2009-2012 The MyBatis Team * *  Licensed under the Apache License, Version 2.0 (the "License"); *  you may not use this file except in compliance with the License. *  You may obtain a copy of the License at * *    http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License. */package org.apache.ibatis.type;import java.sql.Array;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class ArrayTypeHandler extends BaseTypeHandler<Object> { public ArrayTypeHandler() {  super(); } @Override public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {  ps.setArray(i, (Array) parameter); } @Override public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {  Array array = rs.getArray(columnName);  return array == null ? null : array.getArray(); } @Override public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {  Array array = rs.getArray(columnIndex);  return array == null ? null : array.getArray(); } @Override public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {  Array array = cs.getArray(columnIndex);  return array == null ? null : array.getArray(); }}

那它能否識別PostgreSQL的數(shù)組類型并將它自動轉換成Java數(shù)組類型呢?按官方的說法,既然這是默認的typeHandler,那么我們無需做任何配置mybatis會自動嘗試適配,所以直接寫測試代碼看看:

@Testpublic void testFunc1() {  SqlSession session = sqlSessionFactory.openSession();  try {    Map<String, Object> map = new HashMap<String, Object>();    map.put("ids", new Integer[] { 101, 102, 103 });    session.update("com.wl.entity.StudentMapper.testFuncUpdate2", map);    session.commit();  } catch (Exception e) {    e.printStackTrace();  } finally {    session.close();  }}
<update id="testFuncUpdate2" statementType="CALLABLE">  {call func_arr_update (#{ids,mode=IN})} </update>

如上所示,參數(shù)傳的是一個Integer[],直接運行一下junit看看測試結果:

Can't infer the SQL type to use for an instance of [Ljava.lang.Integer;. Use setObject() with an explicit Types value to specify the type to use.

異常log如上所示,在調用AbstractJdbc2Statement類的setObject方法時拋出異常,那么再看看這個方法的源碼:

  /*   * This stores an Object into a parameter.   */  public void setObject(int parameterIndex, Object x) throws SQLException  {    checkClosed();    if (x == null)      setNull(parameterIndex, Types.OTHER);    else if (x instanceof String)      setString(parameterIndex, (String)x);    else if (x instanceof BigDecimal)      setBigDecimal(parameterIndex, (BigDecimal)x);    else if (x instanceof Short)      setShort(parameterIndex, ((Short)x).shortValue());    else if (x instanceof Integer)      setInt(parameterIndex, ((Integer)x).intValue());    else if (x instanceof Long)      setLong(parameterIndex, ((Long)x).longValue());    else if (x instanceof Float)      setFloat(parameterIndex, ((Float)x).floatValue());    else if (x instanceof Double)      setDouble(parameterIndex, ((Double)x).doubleValue());    else if (x instanceof byte[])      setBytes(parameterIndex, (byte[])x);    else if (x instanceof java.sql.Date)      setDate(parameterIndex, (java.sql.Date)x);    else if (x instanceof Time)      setTime(parameterIndex, (Time)x);    else if (x instanceof Timestamp)      setTimestamp(parameterIndex, (Timestamp)x);    else if (x instanceof Boolean)      setBoolean(parameterIndex, ((Boolean)x).booleanValue());    else if (x instanceof Byte)      setByte(parameterIndex, ((Byte)x).byteValue());    else if (x instanceof Blob)      setBlob(parameterIndex, (Blob)x);    else if (x instanceof Clob)      setClob(parameterIndex, (Clob)x);    else if (x instanceof Array)      setArray(parameterIndex, (Array)x);    else if (x instanceof PGobject)      setPGobject(parameterIndex, (PGobject)x);    else if (x instanceof Character)      setString(parameterIndex, ((Character)x).toString());    else if (x instanceof Map)      setMap(parameterIndex, (Map)x);    else    {      // Can't infer a type.      throw new PSQLException(GT.tr("Can''t infer the SQL type to use for an instance of {0}. Use setObject() with an explicit Types value to specify the type to use.", x.getClass().getName()), PSQLState.INVALID_PARAMETER_TYPE);    }  }

我們參數(shù)傳進去的Integer[]數(shù)組是一個Object數(shù)組,而 setObject(int parameterIndex, Object x)方法的第二個參數(shù)是Object,所以這里這里自然無法匹配也就報錯了,那么換成int[]可以嗎?在上面的else if語句中明顯沒有x instanceof int[]這行代碼,所以當然也不行,說到這里也就明確了mybatis默認提供的ArrayTypeHandler是無法自動識別PostgreSQL的數(shù)組類型,我們必須自定義一個參數(shù)為Object[]的ArrayTypeHandler才能實現(xiàn)匹配。

自定義ArrayTypeHandler

如題,先貼上代碼:

package com.wl.util;import java.sql.Array;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import org.apache.ibatis.type.BaseTypeHandler;import org.apache.ibatis.type.JdbcType;import org.apache.ibatis.type.MappedJdbcTypes;import org.apache.ibatis.type.TypeException;@MappedJdbcTypes(JdbcType.ARRAY)public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {  private static final String TYPE_NAME_VARCHAR = "varchar";  private static final String TYPE_NAME_INTEGER = "integer";  private static final String TYPE_NAME_BOOLEAN = "boolean";  private static final String TYPE_NAME_NUMERIC = "numeric";  @Override  public void setNonNullParameter(PreparedStatement ps, int i,      Object[] parameter, JdbcType jdbcType) throws SQLException {    String typeName = null;    if (parameter instanceof Integer[]) {      typeName = TYPE_NAME_INTEGER;    } else if (parameter instanceof String[]) {      typeName = TYPE_NAME_VARCHAR;    } else if (parameter instanceof Boolean[]) {      typeName = TYPE_NAME_BOOLEAN;    } else if (parameter instanceof Double[]) {      typeName = TYPE_NAME_NUMERIC;    }    if (typeName == null) {      throw new TypeException(          "ArrayTypeHandler parameter typeName error, your type is "              + parameter.getClass().getName());    }    Connection conn = ps.getConnection();    Array array = conn.createArrayOf(typeName, parameter);    ps.setArray(i, array);  }  @Override  public Object[] getNullableResult(ResultSet rs, String columnName)      throws SQLException {    return getArray(rs.getArray(columnName));  }  @Override  public Object[] getNullableResult(ResultSet rs, int columnIndex)      throws SQLException {    return getArray(rs.getArray(columnIndex));  }  @Override  public Object[] getNullableResult(CallableStatement cs, int columnIndex)      throws SQLException {    return getArray(cs.getArray(columnIndex));  }  private Object[] getArray(Array array) {    if (array == null) {      return null;    }    try {      return (Object[]) array.getArray();    } catch (Exception e) {    }    return null;  }}

如上所示,我們指定了參數(shù)類型為Object[],這樣就可以接收Integer[]類型的參數(shù)了,關鍵是44~46行,postgresql的驅動類AbstractJdbc4Connection實現(xiàn)了Connect接口的createArrayOf方法,源碼如下:

  public Array createArrayOf(String typeName, Object[] elements) throws SQLException  {    checkClosed();    int oid = getTypeInfo().getPGArrayType(typeName);    if (oid == Oid.UNSPECIFIED)      throw new PSQLException(GT.tr("Unable to find server array type for provided name {0}.", typeName), PSQLState.INVALID_NAME);    char delim = getTypeInfo().getArrayDelimiter(oid);    StringBuffer sb = new StringBuffer();    appendArray(sb, elements, delim);    // This will not work once we have a JDBC 5,    // but it'll do for now.    return new Jdbc4Array(this, oid, sb.toString());  }

這樣通過自定義的ArrayTypeHandler就可以在Mybatis中方便的操作數(shù)組類型數(shù)據(jù)了,最后再測試一下,測試類代碼不變,僅需在調用存儲過程時指定mapper文件的typeHandler即可:

@Testpublic void testFunc1() {  SqlSession session = sqlSessionFactory.openSession();  try {    Map<String, Object> map = new HashMap<String, Object>();    map.put("ids", new Integer[] { 101, 102, 103 });    session.update("com.wl.entity.StudentMapper.testFuncUpdate2", map);    session.commit();  } catch (Exception e) {    e.printStackTrace();  } finally {    session.close();  }}
<update id="testFuncUpdate2" statementType="CALLABLE">  {call func_arr_update (#{ids,mode=IN,typeHandler=com.wl.util.ArrayTypeHandler})} </update>

再次運行junit看一下測試結果:

如上所示,此時已經(jīng)可以成功調用參數(shù)為Integer[]數(shù)組的pg自定義函數(shù)了。

總結

簡單記錄一下在mybatis中調用postgresql自定義函數(shù)時傳遞數(shù)組參數(shù)的解決方案,希望對遇到同樣問題的朋友有所幫助,The End。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

在线 丝袜 欧美 日韩 制服| 成人免费视频久久| 国产精品极品尤物在线观看| 精品国产美女a久久9999| 91中文字幕在线| 丁香高清在线观看完整电影视频| 色婷婷精品久久二区二区蜜臀av| 欧美国产第一页| 精品少妇av| 中文字幕在线观看日韩| gogogo免费高清日本写真| 中文字幕亚洲一区二区av在线| 国产又爽又黄视频| 亚洲最快最全在线视频| 电影在线高清| 看女生喷水的网站在线观看| www久久日com| 精品国产999| 91国内精品久久久| 亚洲精品美女久久| 午夜老司机福利| 欧美精品久久久久久久多人混战| 国产日本亚洲| 久久精品官网| 中文字幕第一页av| 日韩经典一区二区三区| 秋霞av亚洲一区二区三| 在线播放日韩精品| 二区三区偷拍浴室洗澡视频| 99久久国产免费| 天堂网在线观看视频| 久久久久久av无码免费网站| 欧美激情小视频| 人与牲动交xxxxbbbb高清| 国产亚洲欧美日韩精品一区二区三区| 黄色欧美网站| 川上优av一区二区线观看| 中文字幕在线2021| 亚洲日本在线观看| 欧美性色欧美a在线播放| 久久久噜噜噜久久人人看| 偷拍女澡堂一区二区三区| 成人在线视频免费看| 综合视频在线观看| 国产成人av无码精品| 视频在线一区二区三区| 中文字幕在线资源| 婷婷丁香六月天| xxxx日本免费| 超级砰砰砰97免费观看最新一期| 又黄又爽在线免费观看| 精品国产一区二区三区麻豆免费观看完整版| 91精品动漫在线观看| 亚洲精品**不卡在线播he| 日韩欧美在线综合网| 国产一区二区观看| 中文字幕在线影视资源| 日韩一区二区在线看| 亚洲精品乱码久久久久久蜜桃91| 伦伦影院午夜日韩欧美限制| 久久人人爽国产| 美女免费视频黄| 精品久久sese| 人妻精品一区一区三区蜜桃91| 国产精品久久亚洲7777| www.久久色| 日韩精品一区二区三区中文不卡| 国产精品久久久久久久无码| 免费人成自慰网站| 日本三级在线观看网站| 国产精品毛片一区视频播| 日本免费黄网站| 2022中文字幕| 国产欧美精品| 免费精品国产的网站免费观看| 日本一区二区视频在线观看| 久久亚洲资源中文字| 亚欧激情乱码久久久久久久久| 欧美激情第1页| 国内精品在线一区| 日韩人妻一区二区三区| 精品欧美激情在线观看| 国产一区二区三区免费不卡| 黄色精品在线观看| 国产区在线看| 成人天堂av| 中文字幕免费在线看| 美国av一区二区三区| 懂色aⅴ精品一区二区三区蜜月| 女~淫辱の触手3d动漫| 综合国产在线观看| 天堂资源在线观看| 国产91色蝌蚪视频| 中文字幕一二三| 国产成人无码精品| 午夜精品影院在线观看| 欧美黑人性受xxxx喷水| 日韩一级欧洲| 成人影视亚洲图片在线| 国产白嫩美女无套久久| 偷窥国产亚洲免费视频| 国产99在线观看| www99热| 欧美成人午夜做爰视频在线观看| 欧美黄色aaa| av资源一区| 亚洲av成人片色在线观看高潮| 在线码字幕一区| sm国产在线调教视频| 337p日本欧洲亚洲大胆精品| 激情五月婷婷在线| 亚洲另类图片另类电影| 一色屋精品亚洲香蕉网站| 最近中文字幕在线视频| 欧美××××黑人××性爽| 97精品国产97久久久久久久久久久久| 五月天亚洲视频| 成人黄动漫网站免费| 狠狠一区二区三区| 变态黄色小视频网站| 国产精品灌醉下药二区| 欧美残忍xxxx极端| 99久久久久久久| 亚洲欧洲精品在线观看| 波多野结衣视频播放| 亚洲欧洲日本在线| 亚洲综合欧美日韩| 国产一区视频免费观看| 丝袜美腿亚洲一区二区| 91久久偷偷做嫩草影院电| 图片区小说区区亚洲影院| 777精品伊人久久久久大香线蕉| 亚洲成色精品| 国产一区二区三区欧美| 亚洲影院一区| 91玉足脚交白嫩脚丫在线播放| 精品一区二区男人吃奶| 欧美第一淫aaasss性| 国产欧美丝袜| 成人免费高清在线观看| 欧美日韩国产一区二区在线观看| 久久久久久亚洲| 日韩视频免费直播| 国产在线视频一区| 欧美三级日本三级少妇99| 国产一区二区久久久久| 国产成人精品亚洲777人妖| 国产哺乳奶水91在线播放| 91精品人妻一区二区三区| 久热中文字幕在线观看| 成人在线免费小视频| 亚洲欧美一区二区激情| 国产主播中文字幕| 手机看片1024国产| 精品一区二区三区人妻| 成年人av电影| 成人网页在线观看| 日本一区视频在线播放| 日韩女优在线视频| 九七影院理论片| 一个人看的视频www在线观看免费| 91久久国语露脸精品国产高跟| 日韩欧美自拍| 日韩精品视频在线免费观看| 久久成人资源| 亚洲青涩在线| 热99在线观看| 疯狂试爱三2浴室激情视频| 男人通一通女人的下水道| 一本一本久久a久久综合精品蜜桃| 日本一区二区三区视频在线播放| 国产男女猛烈无遮挡| 国产乱色精品成人免费视频| 日韩不卡一区| 国产特级黄色录像| 国产日产精品久久久久久婷婷| 西野翔中文久久精品国产| 国产毛片毛片毛片毛片| 亚洲a级在线观看| www.成年人视频| 69成人免费视频| 日日碰狠狠丁香久燥| 97国产精品久久久| 国产精品乱战久久久| 丰满人妻老熟妇伦人精品| 久久精品中文字幕一区| 欧美精品做受xxx性少妇| 日韩在线国产精品| 人人妻人人添人人爽欧美一区| 蜜臂av日日欢夜夜爽一区| 国产区精品视频在线观看豆花| 国产精品一二三四| 国产美女极度色诱视频www| 影音先锋2020资源| 亚洲熟妇无码一区二区三区导航| 116极品美女视频在线观看| 91精品国产麻豆国产自产在线| 亚洲的天堂在线中文字幕| 亚洲欧美综合国产精品一区| 懂色av.com| 亚洲伊人婷婷| 中文字幕第7页| 欧美free嫩15| 天堂网中文字幕| 久久青青草原亚洲av无码麻豆| 久久久久亚洲AV成人无在| 久久99国产精品久久99果冻传媒| 久久精品一区二区三| 九色蝌蚪视频在线| 中文字幕日韩高清在线| 国产99在线 | 亚洲| 玖玖在线视频| 卡通动漫精品一区二区三区| 欧美成人嫩草网站| 337p粉嫩色噜噜噜大肥臀| 国产精品hd| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 亚洲在线播放| 欧美连裤袜在线视频| 欧美日韩日本国产| 欧美成人自拍| 国产成人亚洲精品自产在线| 中文字幕在线观看一区二区| 精品亚洲精品福利线在观看| 国产真人真事毛片视频| 一区二区三区日韩| 99精品黄色片免费大全| 久热re国产手机在线观看| 亚洲综合在线五月| 亚洲一区二区三区乱码| 欧美日韩一区三区| 丰满少妇高潮在线观看| 在线观看免费黄网站| 波多野结衣国产| 精品91久久久久| 亚洲成人福利片| 欧美不卡高清一区二区三区| 日韩久久免费电影| 成视频免费观看在线看| 一区二区三区高清视频在线观看| www.91在线播放| 婷婷精品在线观看| 国产精品一二区| 欧美成人a视频| av免费在线播放| 欧美久久在线观看| 国产一区视频观看| 亚洲精品久久久久久国| 国产精品扒开腿做爽爽爽a片唱戏| 国产精品18久久久久久麻辣| 亚洲一级视频在线观看| 天天干,天天干| 欧美中日韩在线| 欧美国产日韩精品免费观看| 精品久久久久久久久久久国产字幕| 午夜久久99| 精品一区二区在线免费观看| 日本不卡一区二区| 欧美日韩国产一区二区三区| 美丽的小蜜桃4春潮| 一级片免费看| 青青草国产免费自拍| 久久资源在线| 久久久久久电影| 国产精品青草综合久久久久99| 黄色三级电影网| 91精品在线影院| 国产亚洲精品美女久久久久久久久久| 激情视频免费| 国产一级在线观看视频| 亚洲精品一区二区三区中文字幕| 亚洲精品电影网站| 91在线色戒在线| 亚洲精品自产拍| 真人bbbbbbbbb毛片| 日韩精品成人免费观看视频| 亚洲国产高清一区| 中国女人真人一级毛片| 国内精品**久久毛片app| 国产成人免费在线观看| 99视频精品全部免费在线| 欧美国产精品劲爆| 夜先锋资源网| 亚洲精品免费观看| 99精品视频网站| 亚洲乱码一区| 欧美日夜夜逼| 日韩精品中文字幕在线不卡尤物| 国产大奶在线| 日本h片在线看| av在线最新| 六月婷婷中文字幕| 在线精品视频一区二区三四| 欧美成人手机在线| 欧美理伦片在线播放| 国产精品v欧美精品v日本精品动漫| 欧美性猛交xxxx久久久| 成年人免费网站在线观看| 亚洲国产欧美日韩在线观看第一区| xxxx黑人da| 91色精品视频在线| 欧美a一欧美| 日韩一级黄色大片| 亚洲福利一区二区三区| av软件在线观看| 五月天激情四射| 少妇视频一区| 91豆花视频在线播放| 欧美精品99久久久**| 青青草在线播放| 国产成人亚洲精品狼色在线| 国产精品久久麻豆| 日韩女同强女同hd| 国产91丝袜在线播放九色| 久久综合伊人77777麻豆| 日韩电影在线观看一区二区| 午夜av成人| 一二三四区视频| 一个人看的视频www| 国产一区二区在线视频播放| 日本强好片久久久久久aaa| 亚洲一卡二卡三卡| 国产片在线观看| 国产伦精品一区二区三区四区视频| 99精品热视频只有精品10| av免费播放网址| 国产综合视频一区二区三区免费| 天天干天天插天天操|