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

如何讓iBatis分頁支持Hibernate式的物理分頁

開發 后端
iBatis分頁屬于邏輯分頁,效率相比于Hibernate式的物理分頁較低,本文講述的就是如何在不重新編譯iBatis源碼的前提下,為iBatis分頁引入Hibernate式的物理分頁機制。

一直以來iBatis的分頁都是通過滾動ResultSet實現的,應該算是邏輯分頁吧。邏輯分頁雖然能很干凈地獨立于特定數據庫,但效率在多數情況下不及特定數據庫支持的物理分頁,而Hibernate的分頁則是直接組裝sql,充分利用了特定數據庫的分頁機制,效率相對較高。本文講述的就是如何在不重新編譯iBatis源碼的前提下,為iBatis分頁引入Hibernate式的物理分頁機制。

基本思路就是找到iBatis執行sql的地方,截獲sql并重新組裝sql。通過分析iBatis源碼知道,最終負責執行sql的類是 com.iBatis.sqlmap.engine.execution.SqlExecutor,此類沒有實現任何接口,這多少有點遺憾,因為接口是相對穩定契約,非大的版本更新,接口一般是不會變的,而類就相對易變一些,所以這里的代碼只能保證對當前版本(2.1.7)的iBatis有效。下面是 SqlExecutor執行查詢的方法:

Java代碼

  1. /**    
  2.    * Long form of the method to execute a query    
  3.    *    
  4.    * @param request - the request scope    
  5.    * @param conn - the database connection    
  6.    * @param sql - the SQL statement to execute    
  7.    * @param parameters - the parameters for the statement    
  8.    * @param skipResults - the number of results to skip    
  9.    * @param maxResults - the maximum number of results to return    
  10.    * @param callback - the row handler for the query    
  11.    *    
  12.    * @throws SQLException - if the query fails    
  13.    */    
  14.   public void executeQuery(RequestScope request, Connection conn, String sql, Object[] parameters,     
  15.                            int skipResults, int maxResults, RowHandlerCallback callback)     
  16.       throws SQLException {     
  17.     ErrorContext errorContext = request.getErrorContext();     
  18.     errorContext.setActivity("executing query");     
  19.     errorContext.setObjectId(sql);     
  20.     
  21.     PreparedStatement ps = null;     
  22.     ResultSet rs = null;     
  23.     
  24.     try {     
  25.       errorContext.setMoreInfo("Check the SQL Statement (preparation failed).");     
  26.     
  27.       Integer rsType = request.getStatement().getResultSetType();     
  28.       if (rsType != null) {     
  29.         ps = conn.prepareStatement(sql, rsType.intValue(), ResultSet.CONCUR_READ_ONLY);     
  30.       } else {     
  31.         ps = conn.prepareStatement(sql);     
  32.       }     
  33.     
  34.       Integer fetchSize = request.getStatement().getFetchSize();     
  35.       if (fetchSize != null) {     
  36.         ps.setFetchSize(fetchSize.intValue());     
  37.       }     
  38.     
  39.       errorContext.setMoreInfo("Check the parameters (set parameters failed).");     
  40.       request.getParameterMap().setParameters(request, ps, parameters);     
  41.     
  42.       errorContext.setMoreInfo("Check the statement (query failed).");     
  43.     
  44.       ps.execute();     
  45.       rs = getFirstResultSet(ps);     
  46.     
  47.       if (rs != null) {     
  48.         errorContext.setMoreInfo("Check the results (failed to retrieve results).");     
  49.         handleResults(request, rs, skipResults, maxResults, callback);     
  50.       }     
  51.     
  52.       // clear out remaining results     
  53.       while (ps.getMoreResults());     
  54.     
  55.     } finally {     
  56.       try {     
  57.         closeResultSet(rs);     
  58.       } finally {     
  59.         closeStatement(ps);     
  60.       }     
  61.     }     
  62.     
  63.   }    
#p#

其中handleResults(request, rs, skipResults, maxResults, callback)一句用于處理分頁,其實此時查詢已經執行完畢,可以不必關心handleResults方法,但為清楚起見,下面來看看 handleResults的實現:

Java代碼

  1. private void handleResults(RequestScope request, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException {     
  2.     try {     
  3.       request.setResultSet(rs);     
  4.       ResultMap resultMap = request.getResultMap();     
  5.       if (resultMap != null) {     
  6.         // Skip Results     
  7.         if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {     
  8.           if (skipResults > 0) {     
  9.             rs.absolute(skipResults);     
  10.           }     
  11.         } else {     
  12.           for (int i = 0; i < skipResults; i++) {     
  13.             if (!rs.next()) {     
  14.               break;     
  15.             }     
  16.           }     
  17.         }     
  18.     
  19.         // Get Results     
  20.         int resultsFetched = 0;     
  21.         while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults) && rs.next()) {     
  22.           Object[] columnValues = resultMap.resolveSubMap(request, rs).getResults(request, rs);     
  23.           callback.handleResultObject(request, columnValues, rs);     
  24.           resultsFetched++;     
  25.         }     
  26.       }     
  27.     } finally {     
  28.       request.setResultSet(null);     
  29.     }     
  30.   }    

此處優先使用的是ResultSet的absolute方法定位記錄,是否支持absolute取決于具體數據庫驅動,但一般當前版本的數據庫都支持該方法,如果不支持則逐條跳過前面的記錄。由此可以看出如果數據庫支持absolute,則ibatis內置的分頁策略與特定數據庫的物理分頁效率差距就在于物理分頁查詢與不分頁查詢在數據庫中的執行效率的差距了。因為查詢執行后讀取數據前數據庫并未把結果全部返回到內存,所以本身在存儲占用上應該差距不大,如果都使用索引,估計執行速度也差不太多。 #p# 繼續我們的話題。其實只要在executeQuery執行前組裝sql,然后將其傳給 executeQuery,并告訴handleResults我們不需要邏輯分頁即可。攔截executeQuery可以采用aop動態實現,也可直接繼承SqlExecutor覆蓋executeQuery來靜態地實現,相比之下后者要簡單許多,而且由于SqlExecutor沒有實現任何接口,比較易變,動態攔截反到增加了維護的工作量,所以我們下面來覆蓋executeQuery:

Java代碼

  1. package com.aladdin.dao.ibatis.ext;     
  2.     
  3. import java.sql.Connection;     
  4. import java.sql.SQLException;     
  5.     
  6. import org.apache.commons.logging.Log;     
  7. import org.apache.commons.logging.LogFactory;     
  8.     
  9. import com.aladdin.dao.dialect.Dialect;     
  10. import com.ibatis.sqlmap.engine.execution.SqlExecutor;     
  11. import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;     
  12. import com.ibatis.sqlmap.engine.scope.RequestScope;     
  13.     
  14. public class LimitSqlExecutor extends SqlExecutor {     
  15.     
  16.     private static final Log logger = LogFactory.getLog(LimitSqlExecutor.class);     
  17.          
  18.     private Dialect dialect;     
  19.     
  20.     private boolean enableLimit = true;     
  21.     
  22.     public Dialect getDialect() {     
  23.         return dialect;     
  24.     }     
  25.     
  26.     public void setDialect(Dialect dialect) {     
  27.         this.dialect = dialect;     
  28.     }     
  29.     
  30.     public boolean isEnableLimit() {     
  31.         return enableLimit;     
  32.     }     
  33.     
  34.     public void setEnableLimit(boolean enableLimit) {     
  35.         this.enableLimit = enableLimit;     
  36.     }     
  37.     
  38.     @Override    
  39.     public void executeQuery(RequestScope request, Connection conn, String sql,     
  40.             Object[] parameters, int skipResults, int maxResults,     
  41.             RowHandlerCallback callback) throws SQLException {     
  42.         if ((skipResults != NO_SKIPPED_RESULTS || maxResults != NO_MAXIMUM_RESULTS)     
  43.                 && supportsLimit()) {     
  44.             sql = dialect.getLimitString(sql, skipResults, maxResults);     
  45.             if(logger.isDebugEnabled()){     
  46.                 logger.debug(sql);     
  47.             }     
  48.             skipResults = NO_SKIPPED_RESULTS;     
  49.             maxResults = NO_MAXIMUM_RESULTS;                 
  50.         }     
  51.         super.executeQuery(request, conn, sql, parameters, skipResults,     
  52.                 maxResults, callback);     
  53.     }     
  54.     
  55.     public boolean supportsLimit() {     
  56.         if (enableLimit && dialect != null) {     
  57.             return dialect.supportsLimit();     
  58.         }     
  59.         return false;     
  60.     }     
  61.     
  62. }    

其中:

Java代碼

  1. skipResults = NO_SKIPPED_RESULTS;     
  2. maxResults = NO_MAXIMUM_RESULTS;    
#p#

告訴handleResults不分頁(我們組裝的sql已經使查詢結果是分頁后的結果了),此處引入了類似hibenate中的數據庫方言接口Dialect,其代碼如下:

Java代碼

  1. package com.aladdin.dao.dialect;     
  2.     
  3. public interface Dialect {     
  4.          
  5.     public boolean supportsLimit();     
  6.     
  7.     public String getLimitString(String sql, boolean hasOffset);     
  8.     
  9.     public String getLimitString(String sql, int offset, int limit);     
  10. }    

下面為Dialect接口的MySQL實現:

Java代碼

  1. package com.aladdin.dao.dialect;     
  2.     
  3. public class MySQLDialect implements Dialect {     
  4.     
  5.     protected static final String SQL_END_DELIMITER = ";";     
  6.     
  7.     public String getLimitString(String sql, boolean hasOffset) {     
  8.         return new StringBuffer(sql.length() + 20).append(trim(sql)).append(     
  9.                 hasOffset ? " limit ?,?" : " limit ?")     
  10.                 .append(SQL_END_DELIMITER).toString();     
  11.     }     
  12.     
  13.     public String getLimitString(String sql, int offset, int limit) {     
  14.         sql = trim(sql);     
  15.         StringBuffer sb = new StringBuffer(sql.length() + 20);     
  16.         sb.append(sql);     
  17.         if (offset > 0) {     
  18.             sb.append(" limit ").append(offset).append(',').append(limit)     
  19.                     .append(SQL_END_DELIMITER);     
  20.         } else {     
  21.             sb.append(" limit ").append(limit).append(SQL_END_DELIMITER);     
  22.         }     
  23.         return sb.toString();     
  24.     }     
  25.     
  26.     public boolean supportsLimit() {     
  27.         return true;     
  28.     }     
  29.     
  30.     private String trim(String sql) {     
  31.         sql = sql.trim();     
  32.         if (sql.endsWith(SQL_END_DELIMITER)) {     
  33.             sql = sql.substring(0, sql.length() - 1    
  34.                     - SQL_END_DELIMITER.length());     
  35.         }     
  36.         return sql;     
  37.     }     
  38.     
  39. }    
#p#

接下來的工作就是把LimitSqlExecutor注入ibatis中。我們是通過spring來使用ibatis的,所以在我們的dao基類中執行注入,代碼如下:

Java代碼

  1. package com.aladdin.dao.ibatis;     
  2.     
  3. import java.io.Serializable;     
  4. import java.util.List;     
  5.     
  6. import org.springframework.orm.ObjectRetrievalFailureException;     
  7. import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;     
  8.     
  9. import com.aladdin.dao.ibatis.ext.LimitSqlExecutor;     
  10. import com.aladdin.domain.BaseObject;     
  11. import com.aladdin.util.ReflectUtil;     
  12. import com.ibatis.sqlmap.client.SqlMapClient;     
  13. import com.ibatis.sqlmap.engine.execution.SqlExecutor;     
  14. import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;     
  15.     
  16. public abstract class BaseDaoiBatis extends SqlMapClientDaoSupport {     
  17.     
  18.     private SqlExecutor sqlExecutor;     
  19.     
  20.     public SqlExecutor getSqlExecutor() {     
  21.         return sqlExecutor;     
  22.     }     
  23.     
  24.     public void setSqlExecutor(SqlExecutor sqlExecutor) {     
  25.         this.sqlExecutor = sqlExecutor;     
  26.     }     
  27.     
  28.     public void setEnableLimit(boolean enableLimit) {     
  29.         if (sqlExecutor instanceof LimitSqlExecutor) {     
  30.             ((LimitSqlExecutor) sqlExecutor).setEnableLimit(enableLimit);     
  31.         }     
  32.     }     
  33.     
  34.     public void initialize() throws Exception {     
  35.         if (sqlExecutor != null) {     
  36.             SqlMapClient sqlMapClient = getSqlMapClientTemplate()     
  37.                     .getSqlMapClient();     
  38.             if (sqlMapClient instanceof ExtendedSqlMapClient) {     
  39.                 ReflectUtil.setFieldValue(((ExtendedSqlMapClient) sqlMapClient)     
  40.                         .getDelegate(), "sqlExecutor", SqlExecutor.class,     
  41.                         sqlExecutor);     
  42.             }     
  43.         }     
  44.     }     
  45.     
  46.     ...     
  47.     
  48. }    

其中的initialize方法執行注入,稍后會看到此方法在spring Beans 配置中指定為init-method。由于sqlExecutor是 com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient的私有成員,且沒有公開的set方法,所以此處通過反射繞過java的訪問控制。

下面是ReflectUtil的實現代碼:

Java代碼

  1. package com.aladdin.util;     
  2.     
  3. import java.lang.reflect.Field;     
  4. import java.lang.reflect.Method;     
  5. import java.lang.reflect.Modifier;     
  6.     
  7. import org.apache.commons.logging.Log;     
  8. import org.apache.commons.logging.LogFactory;     
  9.     
  10. public class ReflectUtil {     
  11.     
  12.     private static final Log logger = LogFactory.getLog(ReflectUtil.class);     
  13.     
  14.     public static void setFieldValue(Object target, String fname, Class ftype,     
  15.             Object fvalue) {     
  16.         if (target == null    
  17.                 || fname == null    
  18.                 || "".equals(fname)     
  19.                 || (fvalue != null && !ftype.isAssignableFrom(fvalue.getClass()))) {     
  20.             return;     
  21.         }     
  22.         Class clazz = target.getClass();     
  23.         try {     
  24.             Method method = clazz.getDeclaredMethod("set"    
  25.                     + Character.toUpperCase(fname.charAt(0))     
  26.                     + fname.substring(1), ftype);     
  27.             if (!Modifier.isPublic(method.getModifiers())) {     
  28.                 method.setAccessible(true);     
  29.             }     
  30.             method.invoke(target, fvalue);     
  31.     
  32.         } catch (Exception me) {     
  33.             if (logger.isDebugEnabled()) {     
  34.                 logger.debug(me);     
  35.             }     
  36.             try {     
  37.                 Field field = clazz.getDeclaredField(fname);     
  38.                 if (!Modifier.isPublic(field.getModifiers())) {     
  39.                     field.setAccessible(true);     
  40.                 }     
  41.                 field.set(target, fvalue);     
  42.             } catch (Exception fe) {     
  43.                 if (logger.isDebugEnabled()) {     
  44.                     logger.debug(fe);     
  45.                 }     
  46.             }     
  47.         }     
  48.     }     
  49. }    
#p#

到此剩下的就是通過Spring將sqlExecutor注入BaseDaoiBatis中了,下面是Spring Beans配置文件:

Xml代碼

  1. xml version="1.0" encoding="UTF-8"?>    
  2.     "http://www.springframework.org/dtd/spring-beans.dtd">    
  3.     
  4. <beans>    
  5.         
  6.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    
  7.         <property name="dataSource">    
  8.             <ref bean="dataSource" />    
  9.         property>    
  10.     bean>    
  11.          
  12.         
  13.     <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">    
  14.         <property name="configLocation">    
  15.             <value>classpath:/com/aladdin/dao/ibatis/sql-map-config.xmlvalue>    
  16.         property>    
  17.         <property name="dataSource">    
  18.             <ref bean="dataSource" />    
  19.         property>    
  20.     bean>    
  21.     
  22.     <bean id="sqlExecutor" class="com.aladdin.dao.ibatis.ext.LimitSqlExecutor">    
  23.         <property name="dialect">    
  24.             <bean class="com.aladdin.dao.dialect.MySQLDialect" />    
  25.         property>    
  26.     bean>    
  27.          
  28.     <bean id="baseDao" abstract="true" class="com.aladdin.dao.ibatis.BaseDaoiBatis" init-method="initialize">    
  29.         <property name="dataSource">    
  30.             <ref bean="dataSource" />    
  31.         property>    
  32.         <property name="sqlMapClient">    
  33.             <ref bean="sqlMapClient" />    
  34.         property>    
  35.         <property name="sqlExecutor">    
  36.             <ref bean="sqlExecutor" />    
  37.         property>      
  38.     bean>      
  39.          
  40.     <bean id="userDao" class="com.aladdin.dao.ibatis.UserDaoiBatis" parent="baseDao" />      
  41.     
  42.     <bean id="roleDao" class="com.aladdin.dao.ibatis.RoleDaoiBatis" parent="baseDao" />    
  43.          
  44.     <bean id="resourceDao" class="com.aladdin.dao.ibatis.ResourceDaoiBatis" parent="baseDao" />    
  45.          
  46. beans>    

此后就可以通過調用org.springframework.orm.ibatis.SqlMapClientTemplate的 public List queryForList(final String statementName, final Object parameterObject, final int skipResults, final int maxResults) throws DataAccessException 或 public PaginatedList queryForPaginatedList(final String statementName, final Object parameterObject, final int pageSize) throws DataAccessException 得到iBatis分頁支持Hibernate式的物理分頁結果了。建議使用第一個方法,第二個方法返回的是PaginatedList,雖然使用簡單,但是其獲得指定頁的數據是跨過我們的dao直接訪問ibatis的,不方便統一管理。

【編輯推薦】

  1. iBATIS分頁源碼真相探討
  2. iBATIS緩存cacheModel屬性淺析
  3. ibatis應對批量update
  4. iBATIS與Hibernate間的取舍
  5. iBATIS實例創建的五大步淺析
責任編輯:佚名 來源: Javaeye
相關推薦

2009-07-17 09:24:45

iBATIS分頁

2009-09-23 10:19:08

Hibernate分頁

2009-09-21 18:13:11

Hibernate S

2009-07-21 09:55:45

iBATIS分頁

2009-06-05 09:52:25

struts分頁Hibernate

2010-04-30 08:47:22

Oracle分頁存儲

2009-06-11 14:40:59

Hibernate分頁Hibernate查詢

2009-07-22 11:11:39

iBATIS分頁實例ObjectDataS

2009-09-21 13:42:47

Hibernate查詢

2009-06-04 10:58:15

strutshibernate分頁

2009-02-11 09:37:32

Hibernate分頁技術JSP

2010-05-06 14:01:12

Oracle分頁存儲過

2011-05-03 09:40:58

iBatis

2009-09-22 16:49:42

Hibernate分頁

2009-09-24 14:04:25

Hibernate i

2009-09-21 16:56:14

Hibernateibatis

2025-09-26 07:46:07

2009-07-17 13:13:47

iBATIS Hibe

2009-09-22 13:12:25

Hibernateibatis

2011-08-11 10:22:59

ibatishibernate
點贊
收藏

51CTO技術棧公眾號

7777精品伊久久久大香线蕉语言| 在线视频国产一区| 精品国产伦一区二区三区观看体验 | 青青草自拍偷拍| ww久久综合久中文字幕| ...xxx性欧美| 久久精品magnetxturnbtih| 国产熟妇一区二区三区四区| 欧美高清在线| 亚洲韩国日本中文字幕| 一区二区在线播放视频| 中文字幕有码在线视频| 91香蕉国产在线观看软件| 国产精品mp4| 国产精品精品软件男同| 欧美精品国产白浆久久久久| 欧美日韩精品一区视频| 男女激情无遮挡| 麻豆视频在线| 久久亚洲私人国产精品va媚药| 亚洲综合视频1区| 欧美日韩a v| 亚洲国产激情| 操91在线视频| 日本黄色激情视频| 猛男gaygay欧美视频| 精品久久久久久久久久久院品网 | 久久精品视频网| 91在线在线观看| 中文字幕精品无码亚| 夜夜嗨一区二区| 欧美精品一区三区| 精品一区二区在线观看视频| 亚洲欧美校园春色| 亚洲加勒比久久88色综合| 在线a免费观看| 国产成人a视频高清在线观看| 午夜精品福利在线| 免费极品av一视觉盛宴| 免费黄网站在线| 国产女人水真多18毛片18精品视频| 国产精品一区在线观看| 精品国产无码一区二区三区| 免费xxxx性欧美18vr| 国产91在线播放精品91| 在线观看黄网站| 亚洲美女色禁图| 亚洲3p在线观看| 久久久综合久久久| 亚洲无线一线二线三线区别av| 久久精品99久久久久久久久| 9.1片黄在线观看| 欧美日韩激情在线一区二区三区| 日韩高清不卡av| 在线观看国产免费视频| 国产精品久av福利在线观看| 欧美成人精品福利| www.四虎在线| 久久综合五月婷婷| 精品性高朝久久久久久久| 一区二区三区免费在线观看视频| 欧亚精品一区| 亚洲美女又黄又爽在线观看| 男人舔女人下部高潮全视频| 欧美日韩激情| 久久精品国产成人| 成熟的女同志hd| 欧美一区不卡| 97精品免费视频| 欧美日韩一二三四区| 香蕉久久夜色精品国产| 国产精品久久久| 亚洲一级在线播放| 国产精品一区在线| 国产精品夜夜夜一区二区三区尤| 亚洲欧美色视频| 久久久久久久电影| 一区不卡字幕| 美女网站视频在线| 日韩欧美在线视频免费观看| youjizzxxxx18| 精品国产乱码久久久久久樱花| 日韩视频一区在线观看| 你懂的在线观看网站| 嫩草一区二区三区| 久久夜色精品亚洲噜噜国产mv| 91精品国产高清一区二区三蜜臀| 亚洲高清二区| 国产精品久久久久久久久久久久久久| 亚洲一区二区色| 国产99精品视频| 欧美国产一区二区在线| 91精品国产91久久久久游泳池 | 9999精品| 日韩二区三区在线| 久久av红桃一区二区禁漫| 国产精品黄色| 国产精品mp4| 亚洲国产综合网| 国产亚洲1区2区3区| 国产成年人在线观看| av成人影院在线| 欧美老年两性高潮| 30一40一50老女人毛片| 91九色精品国产一区二区| 午夜精品三级视频福利| 在线免费看av的网站| www.欧美亚洲| 在线视频不卡一区二区| 小早川怜子影音先锋在线观看| 欧美日韩免费不卡视频一区二区三区| 白嫩情侣偷拍呻吟刺激| 99国产精品一区二区| 欧美孕妇与黑人孕交| 国产乱淫av片免费| 国产拍揄自揄精品视频麻豆| 欧美国产日韩激情| 国产精品一区二区三区av| 亚洲新中文字幕| 亚洲国产精品成人无久久精品| 美女视频黄 久久| 欧美精品一区二区视频| 免费在线观看的电影网站| 欧美日韩国产精品自在自线| 中文字幕日韩三级片| 欧美激情综合| 成人午夜一级二级三级| 国产福利片在线| 色天天综合色天天久久| 国产白袜脚足j棉袜在线观看| 婷婷六月综合| 国产热re99久久6国产精品| 精品av中文字幕在线毛片| 亚洲成av人片在线| 国产精品偷伦视频免费观看了| 欧美国产美女| 成人免费观看网址| 香蕉视频在线播放| 欧美亚洲日本一区| 精品无码人妻一区二区免费蜜桃 | 深爱激情综合| 欧美怡春院一区二区三区| 天天干免费视频| 亚洲午夜三级在线| 久久国产免费视频| 欧美日韩成人| www.久久久| 三级福利片在线观看| 欧美成人a∨高清免费观看| 清纯粉嫩极品夜夜嗨av| 国产一区二区福利| 中文字幕中文字幕一区三区| 亚洲欧洲专区| 不卡av日日日| 丰满人妻一区二区三区免费| 夜夜亚洲天天久久| 中国黄色片视频| 亚洲伦伦在线| 久久综合狠狠综合久久综青草| 激情aⅴ欧美一区二区欲海潮| 亚洲精品白浆高清久久久久久| 中文字幕一区二区三区精品 | 天堂av在线一区| 日本欧美色综合网站免费| 亚洲爱爱视频| 久久久av电影| 亚洲av无码一区二区乱子伦| 亚洲电影激情视频网站| aaaaa级少妇高潮大片免费看| 噜噜噜躁狠狠躁狠狠精品视频 | 一本色道久久综合| 鲁丝一区二区三区免费| 欧美黑人疯狂性受xxxxx野外| 亚洲三级 欧美三级| 做爰无遮挡三级| 成人欧美一区二区三区| 国产九九九视频| 亚洲国产国产亚洲一二三| 蜜桃91精品入口| 国产人妖一区| 欧美激情第一页xxx| 婷婷在线观看视频| 色狠狠av一区二区三区| 亚洲波多野结衣| 成人性生交大片免费看中文网站| 欧美日韩亚洲一| 久久精品国产亚洲夜色av网站| 亚洲最大av在线| 亚洲精品动漫| 久久福利视频网| 香蕉视频成人在线| 欧美精品一级二级| 欧美福利视频一区二区| 国产精品卡一卡二| 第一页在线视频| 久久青草久久| 国产女教师bbwbbwbbw| 五月天亚洲色图| 亚洲综合在线中文字幕| 国产成人免费9x9x人网站视频| 波霸ol色综合久久| 日韩在线免费播放| 欧美一区二区免费视频| 怡红院av久久久久久久| 亚洲一区二区中文在线| 日本污视频网站| 99热精品一区二区| 伊人国产精品视频| 视频精品一区二区| 成人免费在线网| 亚洲影视一区二区三区| 日韩精品电影网站| 精品资源在线| **亚洲第一综合导航网站| 性欧美videohd高精| 久久久久中文字幕2018| 黄色免费网站在线观看| 亚洲亚裔videos黑人hd| 午夜一区在线观看| 欧美成人乱码一区二区三区| 136福利视频导航| 色婷婷综合久久久久中文| 日本中文字幕免费观看| 亚洲激情校园春色| 亚洲欧洲综合网| 国产欧美一区二区精品仙草咪| 亚洲色图欧美日韩| 成人国产精品免费观看视频| 手机在线免费毛片| 狠狠色狠狠色合久久伊人| 久久久精品麻豆| 久久精品网址| 精品一区二区中文字幕| 亚洲精品婷婷| 天堂…中文在线最新版在线| 久久99热精品| 无码精品在线观看| 日韩一区二区三免费高清| 亚洲天堂成人在线观看| 精品一区二区三区自拍图片区| 久久99国产精品二区高清软件| 国产91对白在线播放| 尤物网站在线观看| 青青国产91久久久久久| 日本精品一区在线观看| 欧美午夜一区二区福利视频| 六月婷婷激情网| 99国产精品免费视频观看| 午夜精品一区二区三区在线观看 | 精品国产成人亚洲午夜福利| 久久久综合网站| 久久精品视频18| 久久精品人人做人人综合 | 国产精品成人a在线观看| 亚洲视频在线二区| 久久日文中文字幕乱码| 国产又大又长又粗又黄| 亚洲自拍偷拍网| 国产乱子伦精品无码专区| 亚洲第一黄色| 国产在线观看福利| 日韩精品电影在线观看| 黄大色黄女片18第一次| 精品无人区卡一卡二卡三乱码免费卡| 三级一区二区三区| 国产不卡视频在线播放| 日韩无码精品一区二区| 久久久精品tv| 多男操一女视频| 亚洲综合在线观看视频| 成人免费看片98欧美| 日本电影亚洲天堂一区| 一二三区在线播放| 日韩一级高清毛片| 日韩精品123| 中文字幕日韩精品在线| 成人国产免费电影| 91禁国产网站| 成人午夜在线| 国产精品一区二区三区观看| 免费看av成人| 穿情趣内衣被c到高潮视频| 国产日韩精品视频一区二区三区 | 97精品国产97久久久久久久久久久久 | 欧美啪啪小视频| 欧美日韩国产bt| 天堂在线观看视频| 国产一区二区久久精品| 99久久精品免费观看国产| 清纯唯美亚洲综合| 国产欧美视频在线| 欧美日韩电影一区二区| 婷婷成人基地| 99精品免费在线观看| 国产美女久久久久| 久久久久久久久久久久久久久| 成人欧美一区二区三区1314| 国产又黄又粗又爽| 欧美一区二区三区视频免费| 欧美捆绑视频| 欧美国产日韩xxxxx| 国产成人午夜性a一级毛片| 高清视频一区二区三区| 成人午夜国产| 国产97在线 | 亚洲| 国产一区二区日韩精品| 日韩精品电影一区二区| 亚洲综合无码一区二区| 夜夜嗨aⅴ一区二区三区| 日韩av有码在线| 怡红院在线播放| 国产精品亚发布| 久久成人高清| 成人午夜精品久久久久久久蜜臀| 久久成人免费日本黄色| 中文幕无线码中文字蜜桃| 亚洲国产日韩a在线播放| 一级片视频网站| 亚洲色图日韩av| 91超碰国产在线| 97人人香蕉| 91精品国产调教在线观看| 88av.com| 久久久久9999亚洲精品| 久草精品视频在线观看| 欧美一区二区三区免费大片| p色视频免费在线观看| 亲爱的老师9免费观看全集电视剧| 婷婷视频一区二区三区| 中文字幕第一页亚洲| 男男成人高潮片免费网站| 亚洲精品一区二区三区影院忠贞| 婷婷久久综合九色国产成人 | 国产一区免费在线观看| 久久国产亚洲精品| 成人精品视频一区二区| 99久久免费精品高清特色大片| 青娱乐在线视频免费观看| 在线播放亚洲一区| 男人天堂久久久| 国产在线播放不卡| 成人免费a**址| 天堂在线资源视频| 亚洲国产成人私人影院tom| 无码人妻久久一区二区三区 | 成人91视频| 精品999日本| 免费看毛片的网站| 欧美日韩免费在线观看| 性xxxx视频| 热久久99这里有精品| 禁果av一区二区三区| 亚洲不卡视频在线| 中文字幕一区av| 国产a级免费视频| 欧美丰满少妇xxxxx| 精品日产乱码久久久久久仙踪林| 奇米影视亚洲色图| 久久日一线二线三线suv| 精产国品一区二区| 这里只有精品视频在线| 免费日韩成人| 国产精品88久久久久久妇女| 国产成人av一区二区三区在线 | 国产亚洲精品v| 女人又爽又黄免费女仆| 欧美视频一区二区三区在线观看| 香蕉视频在线播放| 99在线观看视频| 国产日韩专区| 午夜国产福利视频| 日韩久久久精品| 中文不卡1区2区3区| 日韩影视精品| 国产精品1024| 久久精品国产成人av| 日韩专区中文字幕| 99久久免费精品国产72精品九九 | 日本一级黄色大片| 亚洲视频在线观看免费| 国产精品99久久免费| 国产欧美日韩小视频| 欧美激情在线免费观看| 不卡视频在线播放| 欧美在线视频免费观看| 91日韩视频| 亚洲综合自拍网| 欧美日本在线一区| 999福利在线视频| 亚洲精品一卡二卡三卡四卡| 国产成人综合网| 中文字幕亚洲乱码熟女1区2区| xxxxx91麻豆| 免费av一区| 久久久久99人妻一区二区三区| 欧美日韩性视频| 91香蕉在线观看| 色综合666| 91一区二区在线观看| 国产精品区在线观看|