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

Let's Fluent:更順滑的 MyBatis

數據庫 其他數據庫
Fluent MyBatis誕生于2019年底,即使與MyBatis Dynamic SQL相比都是晚輩,然而尚處成長期的它就已透出了青出于藍而勝于藍的味道。

 [[404450]]

只需瞅一眼Google Trends上全球Java界最熱門的兩款SQL映射框架近一年的對比數字,就不難了解其實力分布:在此領域,MyBatis早已占領東亞地區開發者市場,并以絕對優勢穩居中國最搶手Java數據庫訪問框架之首。

MyBatis霸榜的底氣來源于其廣袤的生態以及國內眾多大廠的支持。而在琳瑯滿目的MyBatis擴展中,還埋藏著許多“寶藏項目”,來自阿里技術團隊的Fluent MyBatis便是其中一顆獨特的新星。

一 普拉斯們不香了

從iBatis到MyBatis,再到國內團隊以MyBatis Plus為典型代表的諸多周邊工具,"Batis"系列套餐的發展歷程,幾乎又是一部XML的興衰史。最初的iBatis誕生于2002年,彼時XML在Java乃至整個軟件技術界都還相當盛行,和同時期的許多項目一樣,iBatis硬生生的將一堆堆XML塞進千家萬戶的項目里。

許多年后,曾今與iBatis并肩過的社區戰友們紛紛淡出了歷史舞臺,少數像Spring這樣延續至今的佼佼者,也逐漸摒棄XML,向代碼化配置的方式發展。在這方面,iBatis一直是個保守派,即使在MyBatis接過iBatis的衣缽之后,也只是”重磅“推出了支持代碼執行SQL的@Select/@Insert/@Update/@Delete注解(以及相應的4種Provider注解),用來抵擋開發者們對XML泛濫的吐槽,這是在2010年中旬,然后就再無動作。直到2016年底,MyBatis的主要貢獻者之一Jeff Butler正式創建MyBatis Dynamic SQL項目,MyBatis終于開始全面擁抱無XML的代碼化SQL構建。

在從MyBatis到MyBatis Dynamic SQL之間長達6年多的空窗期里,開源社區催生出了許多民間基于MyBatis的無XML代碼方案,其中流行得比較廣泛的是Tk Mybatis、MyBatis Plus這類內置Mapper和自動生成CRUD的擴展庫,一經推出就收獲諸多好評。包括MyBatis Plus里實際上并不太完備的"條件構造器"功能,也由于當時同類解決方案的匱乏而頗受追捧。與此同時,在MyBatis社區之外,一直在默默發展的JOOQ是一款歷史與MyBatis幾乎同樣悠久的純Java動態SQL執行庫,它的用戶群體不大,卻口碑甚好。如今在任意搜索引擎上輸入"MyBatis vs JOOQ",依然能得到幾乎是一邊倒選擇JOOQ的結果,大家給出的理由也非常一致:簡潔、靈活、無需XML,很"Java"。而在MyBatis陣營里,若是拿出MyBatis Plus的"條件構造器"與之正面對陣,只消三個回合,就會被屁滾尿流的打出擂臺。只可惜JOOQ的家底沒有MyBatis那樣殷實,早早走上了商業數據庫支持賣License收費的道路,才讓MyBatis免于在輿論上迎來自己的中年危機。

Fluent MyBatis誕生于2019年底,即使與MyBatis Dynamic SQL相比都是晚輩,然而尚處成長期的它就已透出了青出于藍而勝于藍的味道。

在實現方式上,MyBatis Plus覆寫并替換了部分MyBatis內部類型的方法,整體機制較重,卻也因此能將一些功能細節隱藏到用戶無需關注的內部邏輯里;與之相反,MyBatis Dynamic SQL的實現機制非常輕量,不僅完全基于MyBatis原生的Provider系列注解開發,而且沒有什么隱藏邏輯,對用戶的每張表自動生成相應的Entity、DynamicSqlSupport和Mapper三個類,全部放入用戶的源碼目錄里,因此暴露的細節比較多,代碼侵入性略高。Fluent MyBatis取二者之所長,整體機制與MyBatis Dynamic SQL更接近,同樣基于原生的Provider注解,對用戶的每個表生成Entity類和默認空白的Dao類,不同之處在于它還會通過JVM編譯期代碼增強功能自動生成許多開發者不可更改的標準輔助類,這些代碼無需放入用戶的源碼目錄但能夠在編碼時直接使用,即提供豐富的功能,又保證了用戶代碼的整潔。

在使用方式上,Fluent MyBatis同樣借鑒了前輩們的最優實踐,沒有花里胡哨的注解和配置,直接復用MyBatis連接,所有功能開箱即用。同時由于Fluent MyBatis將所有表字段、條件、操作都以方法調用形式提供,因此獲得了比其他同類項目都更好的IDE語法輔助。舉一個不太復雜的例子:

  1. // 使用Fluent MyBatis構造查詢語句mapper.listMaps(new StudentScoreQuery()    .select    .schoolTerm()    .subject()    .count.score("count")    .min.score("min_score")    .max.score("max_score")    .avg.score("avg_score")    .end()    .where.schoolTerm().ge(2000)    .and.subject.in(new String[]{"英語""數學""語文"})    .and.score().ge(60)    .and.isDeleted().isFalse()    .end()    .groupBy.schoolTerm().subject().end()    .having.count.score.gt(1).end()    .orderBy.schoolTerm().asc().subject().asc().end()); 

MyBatis Dynamic SQL的語法也比較美觀,但字段名和min/max/avg等方法都需要靜態引用,比Fluent MyBatis稍顯遜色。

  1. // 使用MyBatis Dynamic SQL構造查詢語句mapper.selectMany(    select(        schoolTerm,        subject,        count(score).as("count"),        min(score).as("min_score"),        max(score).as("max_score"),        avg(score).as("avg_score")    ).from(studentScore)    .where(schoolTerm, isGreaterThanOrEqualTo(2000))    .and(subject, isIn("英語""數學""語文"))    .and(score, isGreaterThanOrEqualTo(60))    .and(isDeleted, isEqualTo(false))    .groupBy(schoolTerm, subject)    .having(count(score), isGreaterThan(1)) //當前其實還不支持having方法    .orderBy(schoolTerm, subject)    .build(isDeleted, isEqualTo(false))    .render(RenderingStrategies.MYBATIS3)); 

JOOQ的歷史比較悠久,寫出來的代碼鋪天蓋地都是常量字段,功能強大但美觀度欠佳。

  1. // 使用JOOQ構造查詢語句dslContext.select(    STUDENT_SCORE.GENDER_MAN,    STUDENT_SCORE.SCHOOL_TERM,    STUDENT_SCORE.SUBJECT,    count(STUDENT_SCORE.SCORE).as("count"),    min(STUDENT_SCORE.SCORE).as("min_score"),    max(STUDENT_SCORE.SCORE).as("max_score"),    avg(STUDENT_SCORE.SCORE).as("avg_score")).from(STUDENT_SCORE).where(    STUDENT_SCORE.SCHOOL_TERM.ge(2000),    STUDENT_SCORE.SUBJECT.in("英語""數學""語文"),    STUDENT_SCORE.SCORE.ge(60),    STUDENT_SCORE.IS_DELETED.eq(false)).groupBy(    STUDENT_SCORE.GENDER_MAN,    STUDENT_SCORE.SCHOOL_TERM,    STUDENT_SCORE.SUBJECT).having(count().ge(1)).orderBy(    STUDENT_SCORE.SCHOOL_TERM.asc(),    STUDENT_SCORE.SUBJECT.asc()).fetch(); 

MyBatis Plus的條件構造器僅僅封裝了基本的SQL操作,對于字段、條件、別名等都要使用字符串拼接,極易出現由于拼寫失誤引起的SQL異常。

  1. // 使用MyBatis Plus構造查詢語句mapper.selectMaps(new QueryWrapper<StudentScore>()    .select(        "school_term",        "subject",        "count(score) as count",        "min(score) as min_score",        "max(score) as max_score",        "avg(score) as avg_score"    )    .ge("school_term", 2000)    .in("subject""英語""數學""語文")    .ge("score", 60)    .eq("is_deleted", false)    .groupBy("school_term""subject")    .having("count(score)>1")    .orderByAsc("school_term""subject")); 

在Java動態SQL構建的功能完整度方面,當前的排序是MyBatis Plus < MyBatis Dynamic SQL < Fluent MyBatis < JOOQ。

MyBatis Plus條件構造器在功能性上完敗,不僅無法表達JOIN、UNION語句,嵌套查詢之類稍復雜SQL也完全沒招。MyBatis Dynamic SQL支持JOIN和UNION語句,尚未支持嵌套查詢,且缺少HAVING等少量標準SQL語法。Fluent MyBatis支持多表JOIN、UNION、嵌套查詢和幾乎所有標準SQL語法,對于絕大多數場景都妥妥夠用。JOOQ是真正的王者,不僅支持標準SQL語法,連各廠商特有的專有關鍵字和內置方法都沒放過,如MySQL的ON DUPLICATE KEY UPDATE、PostgreSQL的WINDOW、Oracle的CONNECT BY等等。補齊各種SQL語法是一件瑣碎而費力的工作,考慮到SQL語法的總量已經基本不再變化,相信假以時日,各方的差距會逐漸縮小。

除了SQL基本功,特別值得一提的是Fluent MyBatis的獨門絕技:支持動態換表名(FreeQuery/FreeUpdate特性)。在云效項目的開發過程中,由于需要在各種嵌套查詢之上再根據視圖條件動態選擇聚合計算的維度表,多虧了Fluent MyBatis的動態表名功能,才得以在最大程度保留語法構造便利性的情況下,讓代碼復用成為可能。

相比密密麻麻的XML文件,Java代碼在易讀性和可維護性方面有著明顯的優勢。在官方和社區的共同推動下,一個全新的、代碼化的MyBatis生態正在冉冉升起。驀然回首,曾經驕傲的"Plus擴展"們全都不香了。

二 優雅的數據流

初識Fluent MyBatis,最明顯能感受到的特點是它及其便利的IDE語法提示。

基于數據表自動生成的Entity、Mapper、Query、Update等對象,讓所有的數據庫字段和SQL操作都變成了方法,串成平整的流式語句。即使是層層嵌套的查詢,也能表現得錯落有致:

  1. new StudentQuery()    .where.isDeleted().isFalse()    .and.grade().eq(4)    .and.homeCountyId().in(CountyDivisionQuery.class, q -> q        .selectId()        .where.isDeleted().isFalse()        .and.province().eq("浙江省")        .and.city().eq("杭州市")        .end()    ).end(); 

很容易就能看出,上述語句對應的SQL為:

  1. SELECT * FROM studentWHERE is_deleted = falseAND grade = 4AND home_county_id IN (    SELECT id FROM county_division     WHERE is_deleted = false    AND province = '浙江省'    AND city = '杭州市') 

不僅如此,Fluent MyBatis實現的JOIN語法經過幾次調整后,現在的版本也已經十分美觀:

  1. JoinBuilder.from(    new StudentQuery("t1", parameter)        .selectAll()        .where.age().eq(34)        .end()).join(    new HomeAddressQuery("t2", parameter)        .where.address().like("address")        .end()).on(    l -> l.where.homeAddressId(),    r -> r.where.id()).endJoin().build(); 

其中利用Lambada語句表達JOIN條件的設計即充分符合了Java開發者的習慣,又很好的匹配了IDE語法提示的需要,細思極妙。

Fluent MyBatis中的流可以設置條件過濾,例如“僅更新值為非空的字段”:

  1. new StudentUpdate()    .update.name().is(student.getName(), If::notBlank)    .set.phone().is(student.getPhone(), If::notBlank)    .set.email().is(student.getEmail(), If::notBlank)    .set.gender().is(student.getGender(), If::notNull)    .end()    .where.id().eq(student.getId()).end(); 

上面這段代碼等效于MyBatis中的如下XML內容:

顯然Java的流式代碼可讀性遠高于XML文件的尖括號套尖括號的層疊結構。

流是可續接的,對于更復雜的分支條件,Fluent MyBatis中能利用譬如下述語句,充分發揮出Java代碼的靈活性:

  1. StudentQuery studentQuery = Refs.Query.student.aliasQuery()    .select.age().end()    .where.age().isNull().end()    .groupBy.age().apply("id").end();if (config.shouldFilterAge()) {    studentQuery.having.max.age().gt(1L).end();} else if (config.shouldOrder()) {    studentQuery.orderBy.id().desc().end();} 

這種基于外部變量狀態的判斷,已然超出了MyBatis的XML文件的能力范圍。

三 三分鐘源碼淺析

Fluent MyBatis的代碼由Fluent Generator和Fluent MyBatis兩個子項目組成。這對組合與MyBatis Generator搭檔MyBatis Dynamic SQL有異曲同工之妙:Fluent Generator通過讀取數據庫里的表,自動生成Fluent MyBatis所需的Entity和Dao對象;Fluent MyBatis提供編寫SQL語句的函數式DSL。

Fluent Generator子項目的代碼顯得樸實而平鋪直述,程序入口在包結構樹最外層的FileGenerator類型里,由開發者直接調用該類的build()方法,使用鏈式構造器方式傳入需讀取的表名和存放生成文件的目錄等配置。Fluent Generator根據這些信息從數據庫里讀取出表結構,然后為每張表生成Entity和Dao類型的Java文件,放置到約定位置,整個邏輯一氣呵成。值得一提的是,Fluent Generator的配置方法是完全代碼化的,相比MyBatis Generator雖支持純代碼化配置,卻在官方示例繼續沿用XML文件配置輸入的作風更勝一籌。

Fluent Generator生成的Dao類型默認是空的類,它只是一種推薦的數據查詢層結構,通過繼承各自的BaseDao類型,獲得便捷操作Mapper的能力。

Fluent MyBatis子項目的代碼要稍顯豐盈一些,分為三個模塊:

fluent-mybatis 包含各種公共基礎類
fluent-mybatis-test 測試用例
fluent-mybatis-processor 編譯期代碼生成器
fluent-mybatis模塊定義了與代碼生成相關的注解、數據模型和其他輔助類型,它們大多都是幕后英雄:開發者通常不會直接用到這個包中的類。

fluent-mybatis-test模塊包含豐富的測試用例,在一定程度上彌補了Fluent MyBatis當前階段尚不完備的文檔。平時遇到的許多Fluent MyBatis使用問題,若在文檔上無法找到,那么翻一翻代碼庫的測試用例,一定會有意外的收獲。

fluent-mybatis-processor模塊的原理與Lombook工具庫類似,但它并不修改原有的類型,而是掃描Entity類型上的注解,然后動態產生新的輔助類。Fluent Generator產出的Entity類就像是潘多拉盒子,蘊含著Fluent MyBatis魔法的秘密。FluentMybatisProcessor類是整場表演的魔術師,它將每個形如XyzEntity的實體類變幻出一系列輔助類,其中比較關鍵的包括:

XyzBaseDao:繼承BaseDao類型,實現IBaseDao接口,包含獲得Entity相關Mapper、Query、Update類型的方法,是Fluent Generator為用戶生成的空白Dao類的父類。
XyzMapper:實現IEntityMapper,IRichMapper、IWrapperMapper接口,用于構造Query和Update對象,以及執行IQuery或IUpdate類型的SQL指令。
XyzQuery:繼承BaseWrapper、BaseQuery類型,實現IWrapper、IQuery接口,用于組裝查詢語句的基本容器。
XyzUpdate:繼承BaseWrapper、BaseUpdate類型,實現IWrapper、IBaseUpdate接口,用于組裝更新語句的基本容器。
XyzSqlProvider:繼承BaseSqlProvider類型,用于最終組裝SQL語句。
還有XyzMapping、XyzDefaults、XyzFormSetter、XyzEntityHelper:、XyzWrapperHelper等。由fluent-mybatis-processor模塊生成的許多類型都會在編寫業務代碼的時候用到。
一個典型的Fluent MyBatis工作流程是先通過生成的Query或Update類型組裝出執行對象,然后交給Mapper對象下發執行。譬如:

  1. // 構造并執行查詢語句List<StudentEntity> users = mapper.listEntity(    new StudentQuery()        .select.name().score().end()        .where.userName().like("user").end()        .orderBy.id().asc().end()        .limit(20, 10));// 構造并執行更新語句int effectedRecordCount = mapper.updateBy(    new StudentUpdate()        .set.userName().is("u2")        .set.isDeleted().is(true)        .set.homeAddressId().isNull().end()        .where.isDeleted().eq(false).end()); 

Query和Update類型不僅實現IQuery/IUpdate接口,還實現了IWrapper接口,前者用于組裝對象,后者用于讀取對象內容,這是一處很有心的設計。Mapper類型中的許多方法都能接收IQuery或IUpdate接口類型的對象,再通過方法上的@InsertProvider、@SelectProvider、@UpdateProvider或@DeleteProvider注解把實際請求轉給生成的Provider類型。Provider們從約定的Map參數中取出傳入的IWrapper執行對象,使用MapperSql工具類組裝SQL語句,最后交給MyBatis執行。

在Mapper里也有一些直接接受Map對象的方法,可以省去用IQuery/IUpdate描述SQL的過程,進行簡單的插入和查詢。傳入的原始Map對象同樣會在Provider里被讀取出來,用MapperSql組裝SQL語句,再交給MyBatis執行。

Fluent MyBatis的這種基于Provider機制的實現方式不僅能為用戶提供流暢的SQL構造體驗,也能充分復用MyBatis原生的諸多優點,譬如豐富的DB連接器、健全的防SQL注入機制等等,從而確保核心邏輯的穩定可靠。

責任編輯:梁菲 來源: 阿里云云棲號
相關推薦

2011-12-07 20:37:42

iOSAndroid谷歌

2015-12-31 10:35:53

HTTPS 證書HTTPS網絡協議

2021-09-02 15:25:54

技術視頻摳圖

2018-04-08 09:00:00

Let's Encry加密解密

2015-01-12 10:42:02

程序員

2017-10-31 13:20:00

H5翻頁庫框架

2021-12-20 10:00:41

Let's EncryNginxLinux

2020-12-30 05:29:48

API分庫分表

2020-12-07 09:23:46

Windows10Let's Go系統

2015-10-22 13:17:27

Let's EncryHTTPS瀏覽器

2015-12-10 15:53:06

2025-09-09 07:30:00

瀏覽器運維

2015-08-05 15:53:35

power星環

2025-07-04 02:00:00

2017-08-22 15:27:50

冷卻系統數據中心

2011-10-27 15:07:02

松下掃描儀

2017-07-05 16:10:40

Fluent FetcJavaScrip 網絡請求庫

2009-08-27 17:11:44

C# Fluent I

2025-11-03 07:02:20

點贊
收藏

51CTO技術棧公眾號

另类视频在线| 97精品人妻一区二区三区香蕉| 久久黄色影视| 色综合久久88色综合天天| 日本一区二区三区视频免费看| 一级做a爰片久久毛片16| 欧美91福利在线观看| 亚洲二区在线播放视频| 亚洲黄色av网址| 日本理论片午伦夜理片在线观看| 久久久一区二区三区| 成人精品视频99在线观看免费| 精品无码av在线| 日本在线电影一区二区三区| 精品国产91洋老外米糕| 亚洲 欧美 另类人妖| 黄色成人在线网| 国产精品日韩成人| 韩日午夜在线资源一区二区| 91精品国产乱码久久| 国产日韩一区二区三区在线播放 | 东凛在线观看| 丁香婷婷综合色啪| 成人妇女免费播放久久久| 91蜜桃视频在线观看| 欧美黄色一区二区| 在线亚洲午夜片av大片| 亚洲国产综合视频| 国产专区精品| 欧美日韩久久久| 久草资源站在线观看| 激情av在线| 亚洲激情五月婷婷| 欧美爱爱视频网站| 国产午夜精品一区理论片| 北岛玲一区二区三区四区| 亚洲tv在线观看| 国产裸体美女永久免费无遮挡| 亚洲国产黄色| 色综合久久久888| chinese全程对白| 97人人精品| 色综久久综合桃花网| 国产性猛交xx乱| 精品国产乱码久久久| 亚洲精品日韩久久久| 美女又爽又黄视频毛茸茸| 高清日韩欧美| 欧美精品一区二区三区一线天视频| 亚洲18在线看污www麻豆| jizz欧美| 欧美老肥妇做.爰bbww| mm131亚洲精品| 欧美成人福利| 7777精品伊人久久久大香线蕉| 香港日本韩国三级网站| 国产91在线精品| 欧美视频精品在线观看| 精品999在线| 亚洲91在线| 欧美一卡二卡三卡四卡| 性久久久久久久久久久久久久| 精品国产乱码久久久久久樱花| 欧美一区二区网站| 香蕉视频在线观看黄| 777久久精品| 亚洲国产成人一区| av无码av天天av天天爽| 精品国产乱码久久久久久果冻传媒| 亚洲欧美日韩成人| 日本精品在线观看视频| 久久网站免费观看| 久久国产精品免费视频| 久草视频免费在线| 亚洲一区二区网站| 国产精品美乳在线观看| 国产一区二区在线视频观看| 国产激情精品久久久第一区二区| 99电影网电视剧在线观看| 亚洲国产精品suv| 91影院在线免费观看| 欧洲高清一区二区| 国产色在线观看| 亚洲一区二区高清| 久久国产成人精品国产成人亚洲| 91精品影视| 91精品国产aⅴ一区二区| 亚洲香蕉中文网| 精品日韩毛片| 欧美成年人视频网站| 影音先锋亚洲天堂| 免费在线观看成人| 国产精品一区二区在线观看| 男女污污视频在线观看| 亚洲视频香蕉人妖| 国产成人无码a区在线观看视频| 午夜激情成人网| 日韩欧美专区在线| 在线免费看黄视频| 欧美一区免费| 日韩免费视频在线观看| 精品国产18久久久久久| 久久久精品免费免费| 9191国产视频| 欧洲亚洲两性| 亚洲国产私拍精品国模在线观看| 久久国产柳州莫菁门| 一区视频在线| 国产乱人伦真实精品视频| 欧美一区二区公司| 中文字幕日韩一区二区| 日韩av综合在线观看| 国产精品3区| 亚洲深夜福利网站| 日本亚洲色大成网站www久久| 蜜臀av性久久久久蜜臀aⅴ| 国产高清在线精品一区二区三区| 成年人在线免费观看| 午夜精品久久久久久久| 老女人性生活视频| 日韩精品欧美| 日本91av在线播放| 日韩一区二区三区在线观看视频| 综合色天天鬼久久鬼色| 不要播放器的av网站| 国内精品偷拍| 色综合五月天导航| 国产乱码精品一区二区三区精东| 国产午夜精品一区二区三区嫩草 | 天天免费亚洲黑人免费| 亚洲第一精品福利| 免费在线观看黄视频| 九九在线精品视频| 亚洲国产精品www| 在线女人免费视频| 亚洲第一国产精品| 国产亚洲精品久久久久久打不开| 国产在线视频精品一区| 亚洲亚洲精品三区日韩精品在线视频| 亚洲精品福利电影| 日韩电影在线观看中文字幕| 精品一区在线视频| 高潮精品一区videoshd| 女同性恋一区二区| 国产精品一区二区精品| 久久精品视频导航| 97国产成人无码精品久久久| 国产精品免费久久| 日本在线一二三区| 欧美第十八页| 成人精品久久久| 99热国产在线| 亚洲精品一线二线三线无人区| 九九久久免费视频| 成人黄色大片在线观看 | 黄色大片网站在线观看| 99久久精品国产一区| 国内性生活视频| 亚洲免费专区| 国产成人鲁鲁免费视频a| a中文在线播放| 欧美日韩日日骚| 波多野结衣家庭教师| 国产精品一区三区| 青青青青在线视频| 日本一道高清一区二区三区| 欧美综合在线第二页| 国产污视频在线| 91精品久久久久久蜜臀| 69av视频在线| 99re热这里只有精品免费视频| 美女福利视频在线| 精品一区二区三区在线| 成人国产精品日本在线| 91极品在线| 日韩精品欧美激情| 一本色道久久综合精品婷婷| 亚洲激情自拍视频| 日本一区二区三区网站| 人人精品人人爱| 女人床在线观看| 午夜a一级毛片亚洲欧洲| 国产精品福利在线观看网址| 麻豆视频免费在线观看| 亚洲福利精品在线| 黄色一区二区视频| 一区二区三区色| 青青草福利视频| 精品一区二区久久久| 91.com在线| 欧美精品尤物在线观看| 成人午夜电影免费在线观看| 精品裸体bbb| 欧美福利小视频| 超碰免费在线观看| 欧美大黄免费观看| www.av88| 天天操天天综合网| 99久久99久久精品免费看小说.| 高清不卡一区二区在线| 九九视频精品在线观看| 欧美视频一区| 亚洲一区二区三区精品视频| 色婷婷av一区二区三区丝袜美腿| 国产欧美日韩精品专区| av手机在线观看| 久久韩国免费视频| 欧美白人做受xxxx视频| 日韩一卡二卡三卡四卡| 天天射天天干天天| 亚洲一区电影777| 希岛爱理中文字幕| 久久女同精品一区二区| 无码人妻精品一区二区三| 久久国产免费看| 国产激情在线观看视频| 在线观看视频日韩| 色撸撸在线观看| 凹凸成人精品亚洲精品密奴| 精品一区二区三区自拍图片区 | 奇米综合一区二区三区精品视频| 国产一区二区三区小说| 天天色天天射综合网| 秋霞久久久久久一区二区| 久久av国产紧身裤| 亚洲一区美女视频在线观看免费| 日韩三区在线| 日本欧美爱爱爱| 国产传媒av在线| 欧美黑人性猛交| 二区三区在线观看| 久久精品成人动漫| av在线电影免费观看| 亚洲视频免费一区| 你懂的视频在线免费| 亚洲激情自拍图| 婷婷在线免费观看| 欧美mv日韩mv| 殴美一级特黄aaaaaa| 日韩欧美成人一区| 99久久精品国产色欲| 欧美久久婷婷综合色| 中文字幕欧美在线观看| 欧美伊人久久久久久午夜久久久久| 国产专区第一页| 欧美日韩亚洲精品一区二区三区| 日本免费观看视| 精品福利视频导航| 五月婷婷激情网| 疯狂蹂躏欧美一区二区精品| 国产成人在线观看网站| 精品久久久久久电影| 国产精品一区二区6| 欧美视频在线免费| 亚洲黄色免费观看| 色老汉一区二区三区| 在线永久看片免费的视频| 色88888久久久久久影院按摩 | 久久免费公开视频| 亚洲国产精品久久不卡毛片| 日韩网红少妇无码视频香港| 欧美日韩精品在线观看| 一二三区免费视频| 欧美日韩国产一区二区三区地区| 国产精品久久久久久无人区| 这里只有精品电影| 丰满人妻av一区二区三区| 亚洲成人黄色在线| 日本aaa在线观看| 伊人久久男人天堂| 免费在线观看av| 久久久国产一区二区三区| 污片在线免费观看| 18性欧美xxxⅹ性满足| 亚洲精品国产嫩草在线观看| 国产狼人综合免费视频| 9999久久久久| 欧美精品尤物在线| 婷婷久久国产对白刺激五月99| 精品人妻大屁股白浆无码| 亚洲免费在线| 91女神在线观看| 福利视频网站一区二区三区| 欧洲av一区二区三区| 中文字幕中文字幕一区| 国产成人啪精品午夜在线观看| 日本道精品一区二区三区| 国产精品久久久久久无人区| 精品在线观看国产| 里番在线观看网站| 91精品国产91久久| 久久国内精品| 精品一区二区国产| 五月婷婷六月综合| 男女av免费观看| 国产精品2024| 国产精品免费无码| 亚洲成人你懂的| 在线视频你懂得| 日韩av中文在线| 免费**毛片在线| 欧美在线亚洲一区| 视频精品一区| 日韩黄色影视| 最新亚洲激情| 99999精品| 国产日韩欧美亚洲| 国产污视频在线看| 欧美精品自拍偷拍| 黄视频在线观看免费| 欧美激情二区三区| 日韩av懂色| 蜜桃av噜噜一区二区三| 午夜精品久久| 91视频这里只有精品| 久久精品人人做人人爽97| 国产精品1000| 日韩欧美123| 国产精品99999| 欧美一二三视频| 久久黄色影视| 久久成人福利视频| 国产伦精品一区二区三区在线观看| 青娱乐国产视频| 欧美香蕉大胸在线视频观看| 国产综合在线播放| 久久91超碰青草是什么| 日韩综合av| 亚洲一区二区三区免费观看| 日韩电影在线免费| 久久亚洲AV成人无码国产野外| 亚洲国产乱码最新视频 | 久久夜色精品国产欧美乱| 成人在线观看免费视频| 日本视频精品一区| 久久免费国产| 国产精品天天干| 欧美午夜不卡视频| 成人三级黄色免费网站| 国产91在线播放| 国内精品伊人久久久| 福利在线一区二区三区| 国产亚洲一区二区三区在线观看| 六月丁香激情综合| 亚洲美女av网站| 欧美91看片特黄aaaa| 日本不卡一区二区三区在线观看| 美女精品网站| 香蕉视频久久久| 精品视频一区 二区 三区| www 日韩| 国产一区二区在线免费| 1024精品久久久久久久久| 午夜天堂在线视频| 亚洲自拍偷拍欧美| 色噜噜一区二区三区| 青青草成人在线| 日韩电影二区| 99国产精品免费视频| 亚洲一区二区三区在线看| 高h放荡受浪受bl| 538国产精品视频一区二区| 亚洲午夜久久| 在线免费视频一区| 亚洲视频在线一区观看| 午夜精品久久久久久久99老熟妇| 久久免费视频网| 蜜桃一区二区三区| 国内自拍视频网| 一区二区三区久久久| 无码精品视频一区二区三区| 日本韩国在线不卡| 99久久精品网站| 麻豆精品国产传媒av| 色中色一区二区| 成人福利在线观看视频| 国产一区二区三区免费不卡| 免费永久网站黄欧美| 成人信息集中地| 亚洲精品二三区| 久久久免费人体| 国产精品www在线观看| 久久久久久97三级| 国产女主播福利| 欧美在线免费观看| 天天射成人网| 法国伦理少妇愉情| 欧美人狂配大交3d怪物一区| 国产极品人妖在线观看| 奇米888一区二区三区| 国产乱人伦偷精品视频不卡| 久久久精品免费看| 久久久999国产| 精品中文一区| 亚洲精品乱码久久久久久蜜桃欧美| 日韩欧美aaa| 欧美aaa免费| 亚洲一区二区在| 91麻豆swag| 国产www视频|