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

又是搞砸Mybatis源碼的一天

開發
源碼一章肯定是講不完的,所以阿粉會分成幾個章節,并且講源碼的話,代碼肯定比較多,比較干,所以請大家事先準備好開水哦.

1.上期回顧

前面初識 mybatis 章節,阿粉首先搭建了一個簡單的項目,只用了 mybatis 的 jar 包。然后通過一個測試代碼,講解了幾個重要的類和步驟。

先看下這個測試類:

  1. public class MybatisTest { 
  2.     @Test 
  3.     public void testSelect() throws IOException { 
  4.         String resource = "mybatis-config.xml"
  5.         InputStream inputStream = Resources.getResourceAsStream(resource); 
  6.         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
  7.         SqlSession session = sqlSessionFactory.openSession(); 
  8.         try { 
  9.             FruitMapper mapper = session.getMapper(FruitMapper.class); 
  10.             Fruit fruit = mapper.findById(1L); 
  11.             System.out.println(fruit); 
  12.         } finally { 
  13.             session.close(); 
  14.         } 
  15.     } 

這章的話,阿粉會帶著大家理解一下源碼,基于上面測試的代碼。阿粉先申明一下,源碼一章肯定是講不完的,所以阿粉會分成幾個章節,并且講源碼的話,代碼肯定比較多,比較干,所以請大家事先準備好開水哦。

2.源碼分析

這里阿粉會根據 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream) 這段代碼來分析 mybatis 做了哪些事情。

2.1設計模式

通過這段代碼,我們首先分析一下用到了哪些設計模式呢?

首先 SqlSessionFactory 這個類用到了工廠模式,并且上一章阿粉也說到了,這個類是全局唯一的,所以它還使用了單列模式。

然后是 SqlSessionFactoryBuilder 這個類,一看就知道用到了建造者模式。

所以,只看這段代碼就用到了工廠模式,單列模式和建造者模式。

2.2mybatis做了什么事情

這里就開始源碼之旅了,首先 ctrl + 左鍵點擊 build 方法,我們會看到

  1. public SqlSessionFactory build(InputStream inputStream) { 
  2.    return build(inputStream, nullnull); 
  3.  } 

再點擊 build ,然后就是

  1. public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { 
  2.     try { 
  3.       XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); 
  4.       return build(parser.parse()); 
  5.         //后面代碼省略 
  6.         ... 
  7.     } 

首先 XMLConfigBuilder 這個類就是用來解析我們的配置文件 mybatis-config.xml ,調用這個類的構造函數,主要是創建一個 Configuration 對象,這個對象的屬性就對應mybatis-config.xml里面的一級標簽。這里不貼代碼,有興趣的自己點開看下。

然后就是 build(parser.parse()) 這段代碼,先執行 parse()方法,再執行 build() 方法。不過這里,阿粉先說下 build() 這個方法,首先parse() 方法返回的就是 Configuration 對象,然后我們點擊 build 

  1. public SqlSessionFactory build(Configuration config) { 
  2.     return new DefaultSqlSessionFactory(config); 
  3.   } 

這里就是返回的默認的SqlSessionFactory 。

然后我們再說 parse() 方法,因為這個是核心方法。我們點進去看下。 

  1. public Configuration parse() { 
  2.     if (parsed) { 
  3.       throw new BuilderException("Each XMLConfigBuilder can only be used once."); 
  4.     } 
  5.     parsed = true
  6.     parseConfiguration(parser.evalNode("/configuration")); 
  7.     return configuration; 
  8.   } 

首先是 if 判斷,就是防止解析多次。看 parseConfiguration方法。

  1. private void parseConfiguration(XNode root) { 
  2.     try { 
  3.       //issue #117 read properties first 
  4.       propertiesElement(root.evalNode("properties")); 
  5.       Properties settings = settingsAsProperties(root.evalNode("settings")); 
  6.       loadCustomVfs(settings); 
  7.       loadCustomLogImpl(settings); 
  8.       typeAliasesElement(root.evalNode("typeAliases")); 
  9.       pluginElement(root.evalNode("plugins")); 
  10.       objectFactoryElement(root.evalNode("objectFactory")); 
  11.       objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); 
  12.       reflectorFactoryElement(root.evalNode("reflectorFactory")); 
  13.       settingsElement(settings); 
  14.       // read it after objectFactory and objectWrapperFactory issue #631 
  15.       environmentsElement(root.evalNode("environments")); 
  16.       databaseIdProviderElement(root.evalNode("databaseIdProvider")); 
  17.       typeHandlerElement(root.evalNode("typeHandlers")); 
  18.       mapperElement(root.evalNode("mappers")); 
  19.     } catch (Exception e) { 
  20.       throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); 
  21.     } 
  22.   } 

這里就開始了解析mybatis-config.xml里面的一級標簽了。阿粉不全部講,只說幾個主要的。

  1. settings:全局配置,比如我們的二級緩存,延遲加載,日志打印等
  2. mappers:解析dao層的接口和mapper.xml文件
  3. properties:這個一般是配置數據庫的信息,如:數據庫連接,用戶名和密碼等,不講
  4. typeAliases :參數和返回結果的實體類的別名,不講
  5. plugins:插件,如:分頁插件,不講
  6. objectFactory,objectWrapperFactory:實例化對象用的,比如返回結果是一個對象,就是通過這個工廠反射獲取的,不講
  7. environments:事物和數據源的配置,不講
  8. databaseIdProvider:這個是用來支持不同廠商的數據庫
  9. typeHandlers:這個是java類型和數據庫的類型做映射,比如數據庫的 varchar類型對應 java 的String 類型,不講

2.3解析settings

我們點擊 settingsElement(settings) 這個方法 

  1. private void settingsElement(Properties props) { 
  2.   configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior""PARTIAL"))); 
  3.   configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior""NONE"))); 
  4.   configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true)); 
  5.   configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory"))); 
  6.   configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false)); 
  7.   configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), false)); 
  8.   configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true)); 
  9.   configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true)); 
  10.   configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false)); 
  11.   configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType""SIMPLE"))); 
  12.   configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null)); 
  13.   configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null)); 
  14.   configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false)); 
  15.   configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false)); 
  16.   configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope""SESSION"))); 
  17.   configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull""OTHER"))); 
  18.   configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString")); 
  19.   configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true)); 
  20.   configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage"))); 
  21.   configuration.setDefaultEnumTypeHandler(resolveClass(props.getProperty("defaultEnumTypeHandler"))); 
  22.   configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false)); 
  23.   configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), true)); 
  24.   configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false)); 
  25.     configuration.setLogPrefix(props.getProperty("logPrefix")); 
  26.   configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory"))); 
  27.   } 

這個就是設置我們的全局配置信息, setXXX 方法的第一個參數是 mybatis-config.xml 里面標簽里面配置的。有的同學就會問了,阿粉阿粉,我們里面沒有配置那么多啊,這里怎么設置那么多屬性,值是什么呢?那我們看下方法的第二個參數,這個就是默認值。比如 cacheEnabled 這個屬性,緩存開關,沒有配置的話,默認是開啟的 true。所有以后看全局配置的默認值,不用去官網看了,直接在這個方法里面看。

2.4解析mappers

點擊 mapperElement 方法 

  1. private void mapperElement(XNode parent) throws Exception { 
  2.     if (parent != null) { 
  3.       for (XNode child : parent.getChildren()) { 
  4.         if ("package".equals(child.getName())) { 
  5.           String mapperPackage = child.getStringAttribute("name"); 
  6.           configuration.addMappers(mapperPackage); 
  7.         } else { 
  8.           String resource = child.getStringAttribute("resource"); 
  9.           String url = child.getStringAttribute("url"); 
  10.           String mapperClass = child.getStringAttribute("class"); 
  11.           if (resource != null && url == null && mapperClass == null) { 
  12.             ErrorContext.instance().resource(resource); 
  13.             InputStream inputStream = Resources.getResourceAsStream(resource); 
  14.             XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments()); 
  15.             mapperParser.parse(); 
  16.           } else if (resource == null && url != null && mapperClass == null) { 
  17.             ErrorContext.instance().resource(url); 
  18.             InputStream inputStream = Resources.getUrlAsStream(url); 
  19.             XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments()); 
  20.             mapperParser.parse(); 
  21.           } else if (resource == null && url == null && mapperClass != null) { 
  22.             Class<?> mapperInterface = Resources.classForName(mapperClass); 
  23.             configuration.addMapper(mapperInterface); 
  24.           } else { 
  25.             throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one."); 
  26.           } 
  27.         } 
  28.       } 
  29.     } 
  30.   } 

這里有4個判斷 page (包),resource(相對路徑,阿粉配的就是這個,所有按照這個講解源碼),url(絕對路徑),class(單個接口)

XMLMapperBuilder 這個類是用來解析mapper.xml文件的。然后我們點擊 parse 方法。 

  1. public void parse() { 
  2.     if (!configuration.isResourceLoaded(resource)) { 
  3.       configurationElement(parser.evalNode("/mapper")); 
  4.       configuration.addLoadedResource(resource); 
  5.       bindMapperForNamespace(); 
  6.     } 
  7.     parsePendingResultMaps(); 
  8.     parsePendingCacheRefs(); 
  9.     parsePendingStatements(); 
  10.   } 

if 判斷是判斷 mapper 是不是已經注冊了,單個Mapper重復注冊會拋出異常。

configurationElement:解析 mapper 里面所有子標簽。 

  1. private void configurationElement(XNode context) { 
  2.     try { 
  3.       String namespace = context.getStringAttribute("namespace"); 
  4.       if (namespace == null || namespace.equals("")) { 
  5.         throw new BuilderException("Mapper's namespace cannot be empty"); 
  6.       } 
  7.       builderAssistant.setCurrentNamespace(namespace); 
  8.       cacheRefElement(context.evalNode("cache-ref")); 
  9.       cacheElement(context.evalNode("cache")); 
  10.       parameterMapElement(context.evalNodes("/mapper/parameterMap")); 
  11.       resultMapElements(context.evalNodes("/mapper/resultMap")); 
  12.       sqlElement(context.evalNodes("/mapper/sql")); 
  13.       buildStatementFromContext(context.evalNodes("select|insert|update|delete")); 
  14.     } catch (Exception e) { 
  15.       throw new BuilderException("Error parsing Mapper XML. The XML location is '" + resource + "'. Cause: " + e, e); 
  16.     } 
  17.   } 

cacheRefElement:緩存

cacheElement:是否開啟二級緩存

parameterMapElement:配置的參數映射

resultMapElements:配置的結果映射

sqlElement:公用sql配置

buildStatementFromContext:解析 select|insert|update|delete 標簽,獲得 MappedStatement 對象,一個標簽一個對象

bindMapperForNamespace:把namespace對應的接口的類型和代理工廠類綁定起來。 

  1. private void bindMapperForNamespace() { 
  2.     String namespace = builderAssistant.getCurrentNamespace(); 
  3.     if (namespace != null) { 
  4.       Class<?> boundType = null
  5.       try { 
  6.         boundType = Resources.classForName(namespace); 
  7.       } catch (ClassNotFoundException e) { 
  8.         //ignore, bound type is not required 
  9.       } 
  10.       if (boundType != null) { 
  11.         if (!configuration.hasMapper(boundType)) { 
  12.           // Spring may not know the real resource name so we set a flag 
  13.           // to prevent loading again this resource from the mapper interface 
  14.           // look at MapperAnnotationBuilder#loadXmlResource 
  15.           configuration.addLoadedResource("namespace:" + namespace); 
  16.           configuration.addMapper(boundType); 
  17.         } 
  18.       } 
  19.     } 
  20.   } 

看最后 addMapper 方法

  1. public <T> void addMapper(Class<T> type) { 
  2.     if (type.isInterface()) { 
  3.       if (hasMapper(type)) { 
  4.         throw new BindingException("Type " + type + " is already known to the MapperRegistry."); 
  5.       } 
  6.       boolean loadCompleted = false
  7.       try { 
  8.         knownMappers.put(type, new MapperProxyFactory<>(type)); 
  9.         // It's important that the type is added before the parser is run 
  10.         // otherwise the binding may automatically be attempted by the 
  11.         // mapper parser. If the type is already known, it won't try. 
  12.         MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type); 
  13.         parser.parse(); 
  14.         loadCompleted = true
  15.       } finally { 
  16.         if (!loadCompleted) { 
  17.           knownMappers.remove(type); 
  18.         } 
  19.       } 
  20.     } 
  21.   } 

判斷 namespace對應的類是否是接口,然后判斷是否已經加載了這個接口,最后將namespace對應的接口和 MapperProxyFactory 放到 map 容器中。MapperProxyFactory 工廠模式,創建 MapperProxy 對象,這個一看就是代理對象。這個就是根據接口里面的方法獲取 mapper.xml里面對應的sql語句的關鍵所在。具體的等下次講解getMapper()源碼的時候在深入的講解。

3.時序圖  

4.總結

在這一步,我們主要完成了 config 配置文件、Mapper 文件、Mapper 接口解析。我們得到了一個最重要的對象Configuration,這里面存放了全部的配置信息,它在屬性里面還有各種各樣的容器。最后,返回了一個DefaultSqlSessionFactory,里面持有了 Configuration 的實例。

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2019-04-28 09:56:15

程序員互聯網脫發

2021-02-03 21:15:44

Ansible系統運維系統管理員

2012-05-16 11:47:40

Gmail郵件

2018-06-20 09:35:43

碼農科技開發

2019-11-07 15:30:00

EmacsIDE

2024-09-18 07:50:00

超算AI

2015-10-29 11:36:45

Google技術經理程序員

2021-05-11 09:52:13

AI 數據人工智能

2012-08-10 22:44:52

ArchSummit

2017-03-21 21:17:50

大數據數據互聯網

2021-07-15 09:49:08

B站宕機黑客

2013-10-24 15:29:25

MacOS XOS X Maveri

2015-11-04 09:58:17

OpenStack云架構師開源技術

2015-06-04 09:44:20

OpenStackIBMCisco

2023-02-15 09:34:20

公共字段mybatis變量

2015-07-31 10:01:55

win10使用總結

2015-02-10 10:21:22

程序員

2015-07-08 09:43:22

程序員

2015-12-24 18:00:45

資深程序員

2018-10-22 17:52:28

GitHub代碼開發者
點贊
收藏

51CTO技術棧公眾號

岛国av一区| 户外极限露出调教在线视频| 国产精品v一区二区三区| 日韩欧美高清一区| 99爱视频在线| 9191在线| av亚洲精华国产精华精| 国产成人久久久| 黄色a级片在线观看| 老司机精品视频在线播放| 欧洲av一区二区嗯嗯嗯啊| 在线观看18视频网站| 亚州精品国产精品乱码不99按摩| 亚洲免费网站| 久久国产精彩视频| 免费污网站在线观看| 久久免费福利| 91久久精品一区二区三区| 在线观看污视频| 撸视在线观看免费视频| 国产激情91久久精品导航| 国产成人鲁鲁免费视频a| 欧美成人免费观看视频| 国产欧美日韩精品一区二区免费| 91精品麻豆日日躁夜夜躁| 欧美精品99久久| 91三级在线| 国产精品素人视频| 另类欧美小说| 蜜臀久久99精品久久久| 免费美女久久99| 欧美亚洲国产另类| 国产亚洲精品女人久久久久久| 大色综合视频网站在线播放| 亚洲精选一区二区| 无码人妻一区二区三区精品视频| 欧美日韩五码| 一本到不卡精品视频在线观看| 国产一线二线三线女| 黄色免费网站在线观看| 国产日韩欧美高清在线| 极品校花啪啪激情久久| 亚洲AV无码国产精品午夜字幕| 免费成人美女在线观看| 国产成人亚洲精品| 青青视频在线免费观看| 一本色道精品久久一区二区三区| 欧美另类99xxxxx| 国产一区第一页| 日韩成人精品一区| 伊人伊成久久人综合网站| 国精产品一区二区三区| 群体交乱之放荡娇妻一区二区 | 国产女人高潮时对白| 日韩精品国产精品| 国产精品久久久亚洲| 国产精品成人久久久| 日日噜噜夜夜狠狠视频欧美人| 热99精品里视频精品| 极品国产91在线网站| 日韩不卡手机在线v区| 国产精品久久久久久中文字| 五月婷婷六月婷婷| 免费不卡在线观看| 91免费看片网站| 99久久婷婷国产一区二区三区| 加勒比av一区二区| 亚洲xxxx做受欧美| 高清一区二区三区四区| 91网址在线看| 亚洲成人自拍| 91精品国产91久久久久久青草| 一区二区三区高清| 日韩精品 欧美| 原纱央莉成人av片| 91久久精品午夜一区二区| 欧美成人精品欧美一级乱| 天堂√中文最新版在线| 岛国av一区二区| 大荫蒂性生交片| 日韩大片免费观看| 欧美日韩一区二区免费在线观看| av免费观看大全| 亚洲小少妇裸体bbw| 日韩欧美国产一区二区| 亚洲精品无码久久久久久| 欧美特大特白屁股xxxx| 在线视频中文字幕一区二区| 美女网站视频黄色| 电影亚洲一区| 欧美一区二区在线视频| 亚洲精品久久一区二区三区777| 超碰成人在线观看| 日韩成人在线播放| 免费看污片的网站| 99精品视频在线观看免费播放| 在线播放国产一区中文字幕剧情欧美 | 18禁免费无码无遮挡不卡网站| 日韩激情电影| 欧美伊人久久大香线蕉综合69| 性欧美videossex精品| 中文字幕日本一区| 亚洲欧美日韩久久久久久| 国产免费嫩草影院| 欧美黄色一级视频| 2019国产精品自在线拍国产不卡| 精品人妻一区二区三区潮喷在线 | 黄色国产精品视频| 2020国产精品小视频| 日韩女优av电影| 精品无码一区二区三区 | 国产一区二区动漫| 欧美日韩黄色网| 亚洲一区欧美激情| 91精品久久久久久久久中文字幕| 亚洲精品无遮挡| 久久精品水蜜桃av综合天堂| 欧美日韩视频免费在线观看| 九色porny自拍视频在线观看| 欧美丝袜丝交足nylons| 97中文字幕在线观看| 精品久久久久久久久久久下田| 欧美精品免费在线观看| 亚洲图片在线视频| 国产精品91xxx| 日韩在线导航| 多野结衣av一区| 欧美一级欧美三级| 青娱乐国产视频| 亚洲精选国产| 91麻豆国产语对白在线观看| 蜜桃视频在线免费| 亚洲国产欧美在线| 手机av在线免费| 日韩成人av在线资源| 欧美激情一区二区三级高清视频| 中文字幕视频在线播放| 97久久人人超碰| 国产日韩欧美大片| 亚洲伦理一区二区| 国产亚洲视频在线| 国产黄色免费观看| 成人禁用看黄a在线| 中文字幕中文字幕99| 日韩高清中文字幕一区二区| 亚洲精品在线观看网站| 黑人巨大精品一区二区在线| 看片的网站亚洲| 日本一区二区不卡高清更新| 秋霞伦理一区| 亚洲精品国偷自产在线99热 | 琪琪久久久久日韩精品| 久久精品色欧美aⅴ一区二区| 中国一区二区视频| 久久久久国产精品麻豆ai换脸 | 国产精品无码专区在线观看| 日本中文字幕电影在线观看| 亚洲不卡在线观看| 折磨小男生性器羞耻的故事| 午夜精品久久| 91一区二区三区| dy888亚洲精品一区二区三区| 欧美怡红院视频| 国产天堂av在线| 国产在线不卡一区| 2021国产视频| 亚洲成人五区| 欧美精品www在线观看| 精品人妻伦一二三区久久| 亚洲精品视频自拍| 初高中福利视频网站| 国产精品久久久久久| 91久久综合亚洲鲁鲁五月天| 国产剧情在线| 日韩一区二区三区精品视频| 日韩欧美综合视频| 成人在线综合网站| 国产成人无码一二三区视频| 亚洲自拍电影| 国产精品美女免费看| 自拍视频在线| 日韩一卡二卡三卡四卡| 久久久精品视频免费观看| 99久久婷婷国产综合精品电影| 日韩欧美国产免费| 黑人操亚洲人| 亚洲自拍av在线| 538在线观看| 亚洲日本中文字幕免费在线不卡| 波多野结衣一区二区三区在线 | 亚洲xxx自由成熟| 国产日产一区二区| 亚洲人成在线观| 91一区二区视频| 一区二区免费看| 青青草成人免费视频| 久久精品一区二区三区中文字幕| 色噜噜狠狠色综合网| 成人豆花视频| 69精品小视频| 免费国产在线视频| 日韩一区二区三区四区五区六区| 91精品国产乱码在线观看| 久久精品亚洲国产奇米99 | 国产电影精品久久禁18| 99色这里只有精品| 久久久久亚洲| 精品伦精品一区二区三区视频| 成人在线网站| 欧美黄色小视频| 第一视频专区在线| 日韩精品中文字幕在线不卡尤物| 久草手机在线视频| ...xxx性欧美| 成熟人妻av无码专区| 国产a区久久久| 自拍偷拍21p| 欧美日本久久| 亚洲二区三区四区| 久久久久观看| 99理论电影网| 国产精品第一| 欧美在线视频免费播放| 4438x成人网全国最大| 精品视频在线播放| 国产夫妻自拍av| 日韩欧美中文在线| 日本一级片免费看| 亚洲人妖av一区二区| av无码av天天av天天爽| 国产精品综合视频| 亚洲性图一区二区| 亚洲欧美日韩国产一区二区| 国产妇女馒头高清泬20p多| 久久国产影院| 欧美日韩一区二区三| 超碰97成人| 99中文视频在线| av国产精品| 国产精品18久久久久久麻辣| 蜜桃视频m3u8在线观看| 精品少妇v888av| 精品孕妇一区二区三区| 亚洲天天在线日亚洲洲精| 色哟哟中文字幕| 欧美tickling挠脚心丨vk| 亚洲欧美国产高清va在线播放| 91精品国产高清一区二区三区蜜臀| 国产91av在线播放| 色妞www精品视频| 久久久精品国产sm调教| 亚洲欧美日本韩国| 99久久婷婷国产综合| 欧美国产在线观看| 99成人在线观看| 国产精品美女久久福利网站| 成人无码av片在线观看| 国产日韩三级在线| 亚洲午夜福利在线观看| 久久综合色播五月| 加勒比一区二区| 久久免费的精品国产v∧| 精品国产一区在线| 成人动漫中文字幕| 亚洲美女在线播放| 成人avav在线| 无码人妻久久一区二区三区蜜桃| 不卡av免费在线观看| 久久久高清视频| 99精品欧美一区| 国产三级av在线播放| 国产清纯白嫩初高生在线观看91 | 91精品国产高清一区二区三密臀| 日韩欧美中文字幕在线观看 | 欧美色网站导航| 亚洲专区在线播放| 91精品一区二区三区在线观看| 国产精品老熟女视频一区二区| 欧美日韩久久久久久| 草逼视频免费看| 日韩av中文字幕在线播放| 欧美zozo| 中文字幕久热精品在线视频| 久草资源在线观看| 欧美超级免费视 在线| 日韩脚交footjobhdboots| 日韩av电影院| 久久91超碰青草在哪里看| 91亚洲va在线va天堂va国| 丁香一区二区| 任我爽在线视频精品一| 欧美激情1区2区| 欧美 丝袜 自拍 制服 另类| 日韩精品一级中文字幕精品视频免费观看 | 亚洲午夜女主播在线直播| 3p在线观看| 欧美极品在线视频| 美女日批视频在线观看| 国产99久久久欧美黑人| 99精品美女视频在线观看热舞| 成人9ⅰ免费影视网站| 日韩精选在线| 在线观看亚洲视频啊啊啊啊| 欧美午夜电影在线观看| 久草精品在线播放| 国产麻豆成人传媒免费观看| v天堂中文在线| 国产精品美女久久久久久久久| 精品午夜福利在线观看| 欧美亚洲一区二区在线观看| av中文字幕第一页| 亚洲香蕉av在线一区二区三区| 超碰97免费在线| 国产精品国产亚洲伊人久久| 亚洲一区二区电影| 日韩欧美激情一区二区| 亚洲一级高清| 久久久国产欧美| caoporn国产精品| 亚洲人与黑人屁股眼交| 日韩欧美在线网址| 成 人片 黄 色 大 片| 亚洲一级免费视频| av在线麻豆| 成人黄在线观看| 九九久久婷婷| 日本a在线免费观看| 国产又黄又大久久| 欧美一区二区三区粗大| 日韩欧美国产网站| 免费a级片在线观看| 久久久999精品| 成人看片网页| 区一区二区三区中文字幕| 亚洲视频中文| 一级黄色电影片| 亚洲三级在线免费| 中文天堂在线视频| 亚洲欧美国产视频| 日韩精品av| 国产精品乱子乱xxxx| 中文字幕日韩一区二区不卡| 日日躁夜夜躁aaaabbbb| 久久久精品2019中文字幕之3| 国产亚洲精品久久久久久无几年桃| 欧美性受xxxx黑人xyx性爽| 国产福利在线视频| 日韩av片免费在线观看| 欧美大片网址| 国产精品久久久久7777| 国产精品影视天天线| 国产人与禽zoz0性伦| 欧美性一区二区| eeuss影院www在线播放| 国产91色在线播放| 影视先锋久久| 日韩精品―中文字幕| 久久一区二区视频| 久久久久久久久久久久久av| 日韩精品中文字幕视频在线| 草草在线视频| 麻豆成人小视频| 奇米影视一区二区三区小说| 公肉吊粗大爽色翁浪妇视频| 欧美在线免费视屏| 91精品专区| 91久久国产综合久久91精品网站| 欧美成人中文| 人妻 丝袜美腿 中文字幕| 亚洲午夜精品网| 欧美一级视频免费| 97视频色精品| 欧美日韩激情| 日韩精品视频一二三| 亚洲欧美一区二区不卡| 亚洲成熟女性毛茸茸| 久久久综合av| 欧美码中文字幕在线| 亚洲午夜精品一区| 亚洲精品第1页| 亚洲欧洲国产综合| 国产精品成人免费电影| 伊人久久大香线| 亚洲少妇一区二区三区| 欧美性色19p| 香蕉视频网站在线观看| 成人免费看吃奶视频网站| 亚洲视频一二| 亚洲精品国产一区黑色丝袜| 欧美久久久久中文字幕| 污片在线免费观看| 国产精品视频入口| 免费观看在线综合色| 九九视频在线观看| 亚洲免费电影在线观看| 色成人综合网| avove在线观看| 亚洲国产精品成人综合| 亚洲黄色a级片| 国产精品久久97|