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

首頁 > 學院 > 開發設計 > 正文

開源面向對象數據庫:db4o 查詢方式

2019-11-17 05:55:39
字體:
來源:轉載
供稿:網友

2006 年 11 月 20  這篇文章是 開源面向對象數據庫 db4o 之旅 系列文章的第二篇,介紹了面向對象數據庫 db4o 的安裝、啟動以及三種查詢語言,并對三種查詢語言做了比較。

前言

     在 開源面向對象數據庫 db4o 之旅 系列文章的第一部分:初識 db4o 中,作者介紹了 db4o 的歷史和現狀,應用領域,以及和 ORM 等的比較。在這篇文章中,作者將會介紹 db4o 的安裝、啟動以及三種不同的查詢方式:QBE(Query by Example)、SODA(Simple Object Database access) 以及 NQ(Native Queries),并分別通過這三種不同的途徑實現了兩個關聯對象的查詢。本文還示范了開發中最經常用到的幾個典型功能的 db4o 實現。

下載和安裝 db4o

     db4o 所有最新的版本都可以直接在官方網站上下載,進入 db4o 的下載頁面,我們可以看到最新的 for java 穩定版本是 5.5,包括 JAR、源代碼、入門文檔、API 等內容的完整的打包文件只有 6 MB,db4o 還有一個對象數據庫治理工具 ObjectManager,目前版本是 1.8(請在參考資源中下載)。

    接著在 Eclipse 中新建 Java 項目,把 db4o 對象數據庫引擎包 db4o-5.5-java5.jar 導入進項目。由于 db4o 支持多種版本的 JDK,除了 for JDK 5.0 的 db4o-5.5-java5.jar 外,還有 for JDK 1.1、1.2-1.4 的 JAR 包,以適應多種環境。與 Hibernate、iBATIS SQL Maps 相比,db4o 更加自然,無需過多地引用第三方支持庫。

開啟數據庫

    db4o 怎樣進行對象持久化呢?通過瀏覽目錄可以發現,與傳統的 RDBMS 一樣,db4o 也有自己的數據庫文件, 在 db4o 中數據庫文件的后綴名是“*.yap”。讓我們先來了解一下 db4o 對象數據庫引擎的主要包結構:

  • com.db4o
    com.db4o 包含了使用 db4o 時最經常用到的功能。兩個最重要的接口是 com.db4o.Db4o 和 com.db4o.ObjectContainer。com.db4o.Db4o 工廠是運行 db4o 的起點,這個類中的靜態方法可以開啟數據庫文件、啟動服務器或連接一個已經存在的服務器,還可以在開啟數據庫之前進行 db4o 環境配置。com.db4o.ObjectContainer 接口很重要,開發過程中 99% 的時間都會用到它,ObjectContainer 可在單用戶模式下作為數據庫實例,也可作為 db4o 服務器的客戶端。每個 ObjectContainer 實例都有自己的事務。所有的操作都有事務保證。當打開 ObjectContainer,就已經進入事務了,commit() 或 rollback() 時,下一個事務立即啟動。每個 ObjectContainer 實例維護它自己所治理的已存儲和已實例化對象,在需要 ObjectContainer 的時候,它會一直保持開啟狀態,一旦關閉,內存中數據庫所引用的對象將被丟棄。
  • com.db4o.ext
    你也許想知道為什么在 ObjectContainer 中只能看見很少的方法,原因如下:db4o 接口提供了兩個途徑,分別在 com.db4o 和 com.db4o.ext 包中。這樣做首先是為了讓開發者能快速上手;其次為了讓其他產品能更輕易的復制基本的 db4o 接口;開發者從這一點上也能看出 db4o 是相當輕量級的。每個 com.db4o.ObjectContainer 對象也是 com.db4o.ext.ExtObjectContainer 對象。可以轉換成 ExtObjectContainer 獲得更多高級特性。
  • com.db4o.config
    com.db4o.config 包含了所有配置 db4o 所需的類。
  • com.db4o.query
    com.db4o.query 包包含了構造“原生查詢, NQ(Native Queries)”所需的 PRedicate 類。NQ 是 db4o 最主要的查詢接口。

    db4o 提供兩種運行模式,分別是本地模式和服務器模式。本地模式是指直接在程序里打開 db4o 數據庫文件進行操作:

ObjectContainer db = Db4o.openFile("auto.yap");

而服務器模式則是客戶端通過 IP 地址、端口以及授權口令來訪問服務器:

服務器端:

ObjectServer server=Db4o.openServer("auto.yap",1212);server.grantAccess("admin","123456");


客戶端:
ObjectContainer db=Db4o.openClient("192.168.0.10",1212,"admin","123456");

    兩種方式都可以得到 ObjectContainer 實例,就目前 Java EE 應用環境來看,服務器模式更有現實意義;而本地模式更適合于嵌入式應用。為了簡化演示,本文在下面的例子都將采用本地模式。

在下面的例子里,我們都會用到下面兩個對象: People 和 AutoInfo 對象。

People 對象清單1:


清單1. People 對象

				package bo;public class People {	private java.lang.Integer _id;	private java.lang.String _name;	private java.lang.String _address;	private java.util.List<AutoInfo> _autoInfoList;	public java.lang.Integer getId() {		return _id;	}	public void setId(java.lang.Integer _id) {		this._id = _id;	}	public java.lang.String getName() {		return _name;	}	public void setName(java.lang.String _name) {		this._name = _name;	}	public java.lang.String getAddress() {		return _address;	}	public void setAddress(java.lang.String _address) {		this._address = _address;	}	public java.util.List<AutoInfo> getAutoInfoList() {		return this._autoInfoList;	}	public void addAutoInfo(AutoInfo _autoInfoList) {		if (null == this._autoInfoList)			this._autoInfoList = new java.util.ArrayList<AutoInfo>();		this._autoInfoList.add(_autoInfoList);	}}

 

AutoInfo 對象清單2:


清單2. AutoInfo 對象

				package bo;public class AutoInfo{	private java.lang.Integer _id;	private java.lang.String _licensePlate;	private bo.People _ownerNo;	public java.lang.Integer getId () {		return _id;	}	public void setId (java.lang.Integer _id) {		this._id = _id;	}	public java.lang.String getLicensePlate () {		return _licensePlate;	}	public void setLicensePlate (java.lang.String _licensePlate) {		this._licensePlate = _licensePlate;	}	public bo.People getOwnerNo () {		return this._ownerNo;	}	public void setOwnerNo (bo.People _ownerNo) {		this._ownerNo = _ownerNo;	}}

    利用 set 方法把新對象存入 ObjectContainer,而對 ObjectContainer 中已有對象進行 set 操作則是更新該對象。db4o 保存數據庫很簡單,下面就是一個段完整的保存對象的代碼:

AutoInfo 對象清單3:


清單3

				package com;import bo.AutoInfo;import bo.People;import com.db4o.Db4o;import com.db4o.ObjectContainer;public class DB4OTest{		public static void main(String[] args){		//打開數據庫		ObjectContainer db = Db4o.openFile("auto.yap");		try{			//構造 People 對象			People peo = new People(); 			peo.setId(1);			peo.setAddress("成都市");			peo.setName("張三");			//構造 AutoInfo 對象			AutoInfo ai = new AutoInfo();			ai.setId(1);			ai.setLicensePlate("川A00000");			//設置 People 和 AutoInfo 的關系			ai.setOwnerNo(peo);			peo.addAutoInfo(ai);			//保存對象			db.set(peo);		}finally{			//關閉連接			db.close();		}	}}

    當我們運行上述代碼,db4o 會自動創建“auto.yap”文件。讓我們來看看到底保存成功沒有,打開 ObjectManager 工具,如圖 1 所示。



圖1. 對象數據庫治理工具
開源面向對象數據庫:db4o 查詢方式(圖一)

QQRead.com 推出數據恢復指南教程 數據恢復指南教程 數據恢復故障解析 常用數據恢復方案 硬盤數據恢復教程 數據保護方法 數據恢復軟件 專業數據恢復服務指南

    “File”->“Open File”->選擇剛才我們保存的“auto.yap”文件(“auto.yap”文件可在項目的根目錄下找到),最新的 ObjectManager 1.8 版本為我們提供了“Read Only”方式讀取數據庫文件,避免 ObjectManager 占用數據庫文件所導致的程序異常。

    打開之后,如圖 2 所示,剛才存貯的 People 對象已經在數據庫中了,并且還可以很直觀的看到 AutoInfo 對象也放入了 ArrayList 中。這種可視化的對象關系有利于我們對數據的理解,是傳統 RDBMS 無法比擬的。有些開發者會說 ObjectManager 工具略顯簡單,這點我想隨著 db4o 的不斷發展會加入更多的特性。在這個工具中,我們意外的發現了 Java 集合對象的蹤影,db4o 把與 ArrayList 有直接關系的所有接口和父類都保存了,這樣顯得更直觀。

    在此,我保留了 _id 屬性,這是因為通常在 Java EE 環境中,DAO 第一次不是把整個對象都返回到表現層,而是只返回了“標題”、“發布時間”這些信息(并隱式的返回id),接著 DAO 與數據庫斷開;要查看詳情(比如文章內容)就需要進行 findById 操作,這時 DAO 要再次與數據庫交互,只有唯一標識符才能正確地找到對象。這種懶加載方式也是很多書籍所推薦的。

    回到本文的范例程序中,這個 _id 屬性可由人工編碼實現的“序列”進行賦值,當然 db4o 也提供了內部標識符 Internal IDs,如圖 2 中的 id=1669;以及 UUIDs。


圖2. 對象結構
開源面向對象數據庫:db4o 查詢方式(圖二) 

查詢數據庫

    和 RDBMS 一樣,db4o 也有自己的查詢語言,分別是 QBE(Query by Example)、NQ(Native Queries)、SODA(Simple Object Database Access),db4o 更推薦使用 NQ 進行查詢。NQ 方式提供了非常強大的查詢功能,支持原生語言,也就意味著你可以使用 Java 來判定該對象是否符合條件,這是其他數據庫查詢語言無法比擬的。在某些情況下, db4o 核心會將 NQ 翻譯成 SODA 以獲得更高的性能。下面具體介紹一下這三種查詢語言。

QBE(Query by Example)

    QBE 規范可在這里下載。QBE 最初由 IBM 提出,同時業界也有許多和 QBE 兼容的接口,包括聞名的 Paradox。有些系統,比如微軟的 Access,它的基于表單的查詢也是受到了部分 QBE 思想的啟發。在 db4o 中,用戶可借用 QBE 快速上手,可以很輕易適應 db4o 存取數據的方式。

    當利用 QBE 為 db4o 提供模板(example)對象時,db4o 將返回所有和非默認值字段匹配的全部對象。內部是通過反射所有的字段和構造查詢表達式(所有非默認值字段結合”AND”表達式)來實現。

例如,利用 QBE 查找到車牌號為“川A00000”的車主姓名,這是一個級聯查詢。清單4:


清單4

				package com;import java.util.List;import bo.AutoInfo;import com.db4o.Db4o;import com.db4o.ObjectContainer;public class DB4OTest{		public static void main(String[] args){		//打開數據庫		ObjectContainer db = Db4o.openFile("auto.yap");		try{			//構造模板對象			AutoInfo ai = new AutoInfo();			ai.setLicensePlate("川A00000");			//查詢對象			List<AutoInfo> list = db.get(ai);	    	for(int x = 0; x < list.size(); x++){	    		System.out.println("車主姓名:"+list.get(x).getOwnerNo().getName());			}		}finally{			//關閉連接			db.close();		}	}}

    但是 QBE 也有明顯的限制:db4o 必須反射模板(example)對象的所有成員;無法執行更進一步的查詢表達式(例如 AND、OR、NOT 等等);不能約束 0(整型)、””(空字符串)或者 null(對象),因為這些都被認為是不受約束的。要繞過這些限制,db4o 提供了 NQ(Native Queries)。

 

SODA(Simple Object Database Access)

    SODA ,簡單對象數據庫訪問,請查看官方站點,其中一位主要維護者是 Carl Rosenberger,Carl 正是 db4o 首席架構師。

    SODA 就是一種與數據庫通訊的對象 API。最終的目標是實現類型安全、對象復用、最小的字符串使用、與編程語言無關等特性。SODA 是 db4o 最底層的查詢 API,目前 SODA 中使用字符串來定義字段,這樣將不能實現類型安全也無法在編譯時檢查代碼,而且寫起來較麻煩,當然要達到設計目標這個階段是必須的。大部分情況下 NQ(Native Queries)是很好的查詢接口,不過碰到動態生成查詢的時候 SODA 就大有作為了。

通過 SODA 查找到車牌號為“川A00000”的車主姓名。清單5:



清單5

				package com;import java.util.List;import bo.AutoInfo;import com.db4o.Db4o;import com.db4o.ObjectContainer;import com.db4o.query.Query;public class DB4OTest{		public static void main(String[] args){		//打開數據庫		ObjectContainer db = Db4o.openFile("auto.yap");		try{			//構造查詢對象			Query query=db.query();			//設置被約束實例			query.constrain(AutoInfo.class);			//設置被約束實例的字段和約束條件			query.descend("_licensePlate").constrain("川A00000");			//查詢對象			List<AutoInfo> list = query.execute();	    	for(int x = 0; x < list.size(); x++){	    		System.out.println("車主姓名:"+list.get(x).getOwnerNo().getName());			}		}finally{			//關閉連接			db.close();		}	}}

    通過 API,發現 Query 實例增加了 sortBy 按字段排序方法和 orderAscending正序、orderDescending 倒序排列方法,SODA 比 QBE 更進了一步。

NQ(Native Queries)

    出色總是在最后出場,NQ 才是 db4o 查詢方式中最出色的地方!有沒有想過用你熟悉的的編程語言進行數據庫查詢呢?要是這樣,你的查詢代碼將是 100% 的類型安全、100% 的編譯時檢查以及 100% 的可重構,很奇妙吧?NQ 可以做到這些。

    有兩篇論文專門講解了 NQ 的基本概念和設計思路,分別是 《Cook/Rosenberger,持久對象原生數據庫查詢語言》 和 《Cook/Rai,Safe Query Objects: Statically Typed Objects as Remotely Executable Queries》。作為結果集的一部分,NQ 表達式必須返回 true 值來標記特定實例。假如可能的話 db4o 將嘗試優化 NQ 表達式,并依靠索引來運行表達式。

通過 NQ 查找到車牌號為“川A00000”的車主姓名。清單6:


清單6

				package com;import java.util.List;import bo.AutoInfo;import com.db4o.Db4o;import com.db4o.ObjectContainer;import com.db4o.query.Predicate;public class DB4OTest{		public static void main(String[] args){		//打開數據庫		ObjectContainer db = Db4o.openFile("auto.yap");		try{			List <AutoInfo> list = db.query(new Predicate<AutoInfo>() {				public boolean match(AutoInfo ai) {			    	//這樣才是類型安全的			        return ai.getLicensePlate().equals("川A00000");			    }			});	    	for(int x = 0; x < list.size(); x++){	    		System.out.println(list.get(x).getOwnerNo().getName());			}		}finally{			//關閉連接			db.close();		}	}}

QQRead.com 推出數據恢復指南教程 數據恢復指南教程 數據恢復故障解析 常用數據恢復方案 硬盤數據恢復教程 數據保護方法 數據恢復軟件 專業數據恢復服務指南

    必須指出 NQ 的一個的問題是:在內部,db4o 設法把 NQ 轉換成 SODA。但并不是所有的查詢表達式都可以成功轉換。有些查詢表達式的流向圖(flowgraph)非常難于分析。這種情況下,db4o 將不得不實例化一些持久對象來真實地運行 NQ 表達式。

    正在開發中的 NQ 查詢優化器就可以化解這個障礙,它將分析 NQ 表達式的每個部分,以確保最少量的實例化對象,以此提高性能。當然,優化器的不是靈丹妙藥,要害還需要自己多優化代碼。

開發 Java EE 項目經常會用到分頁,怎樣用 NQ 實現呢?向數據庫寫入六條記錄。清單7:


清單7

				package com;import java.util.List;import bo.AutoInfo;import com.db4o.Db4o;import com.db4o.ObjectContainer;import com.db4o.query.Predicate;public class DB4OTest{		public static void main(String[] args){		//打開數據庫		ObjectContainer db = Db4o.openFile("auto.yap");		try{			List<AutoInfo> list = db.query(new Predicate<AutoInfo>() {				public boolean match(AutoInfo ai) {			        return true;			    }			});			//記錄總數			Integer count = list.size();			//每頁兩條,分三頁	    	for(int x = 0; x < 3; x++){	    		System.out.println("第"+x+"頁:"+list.get(x*2).getLicensePlate());	    		System.out.println("第"+x+"頁:"+list.get(x*2+1).getLicensePlate());			}		}finally{			//關閉連接			db.close();		}	}}


    我們發現,在進行 NQ 查詢時并沒有加入任何條件(無條件返回 true),是不是相當于遍歷了整個數據庫?db4o 的設計者早就想到了這個問題,當 db.query() 執行完畢返回 list 實例的時候,db4o 只是與數據庫同步取出內部 IDs 而已,并沒有把所有的 AutoInfo 對象全部取出,只有在 list.get(x*2).getLicensePlate() 之后才會去根據 IDs 取出記錄。所以不必擔心性能問題。

結論

    db4o 為開發者提供了多種查詢方式,這些方式都很靈活。要引起大家注重的是:靈活在帶來便利的同時也對開發者自身素質提出了更高的要求,(比如排序,既可以用 SODA 也可以用 Java 集合對象實現)在開發過程中一定要形成某種統一的開發模式,這樣 db4o 才能最高效能地為我所用。



 

參考資料

學習

  • “面向對象數據庫 db4o 之旅,第 1 部分:初識 db4o”:(developerWorks Java ,2006 年 10月):介紹了 db4o 的歷史和現狀,應用領域,以及和 ORM 等的比較。

  • db4o 開發者論壇:討論 db4o 技術。

  • db4o 中國開發者論壇:討論 db4o 技術的中文論壇。

  • ODMG 官方網站:了解 ODMG 技術。

  • SODA 官方網站:了解簡單對象數據庫訪問技術。

  • Java 技術專區:這里有數百篇有關 Java 編程各方面的文章。

  • developerWorks Java 論壇:學習 Java 技術


獲得產品和技術

  • db4o 官方網站:db4o 最新信息以及 db4o 下載。

  • 下載 db4o 對象數據庫治理工具 ObjectManager 1.8 for Windows。



 

作者簡介

開源面向對象數據庫:db4o 查詢方式(圖三)

開源面向對象數據庫:db4o 查詢方式(圖三)

Rosen Jiang 來自成都,是 db4o 和 OO 的忠實 fans,是 2005 年 db4o 的 dvp 獲得者之一。他正在 J2me 應用中使用 db4o,你可以通過 rosener_722@hotmail.com 和他聯系。


開源面向對象數據庫:db4o 查詢方式(圖三)

開源面向對象數據庫:db4o 查詢方式(圖三)

Chris 來自香港,熱愛開源和 db4o。他創辦了中國最火熱的 Java 和開源社區 Matrix(http://www.Matrix.org.cn), 你可以通過 chris@Matrix.org.cn 和他聯系。


開源面向對象數據庫:db4o 查詢方式(圖三)

開源面向對象數據庫:db4o 查詢方式(圖三)

張黃矚,熱愛開源軟件,熟悉 Java/C/C++ 編程語言,對數據庫技術網絡技術均感愛好。你可以通過 zhanghuangzhu@Gmail.com 聯系他。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲一区二区少妇| 国产一区二区成人| 国内外成人免费激情在线视频| 亚洲成人动漫在线播放| 亚洲国产精品专区久久| 在线播放国产精品| 92版电视剧仙鹤神针在线观看| 成人免费观看a| 亚洲欧美日韩中文在线制服| 国产精品女人网站| 国产精品jizz在线观看麻豆| 国产精品国产三级国产专播精品人| 亚洲色在线视频| 中文国产成人精品| 国产91精品高潮白浆喷水| 91国产视频在线| 欧美精品在线免费观看| 综合网日日天干夜夜久久| 亚洲国产精品va在看黑人| www欧美日韩| 国自在线精品视频| 热99久久精品| 欧美黄色免费网站| 亚洲最新av网址| 亚洲影视九九影院在线观看| 精品视频中文字幕| 夜色77av精品影院| 欧美亚洲一级片| 亚洲欧美日韩天堂一区二区| 亚洲精品久久视频| 欧美性猛交xxxx黑人猛交| 欧美富婆性猛交| 成人免费视频网址| 奇门遁甲1982国语版免费观看高清| 国产欧美日韩免费| 欧美制服第一页| 在线播放日韩欧美| 浅井舞香一区二区| 欧美精品免费在线观看| www.国产精品一二区| 日韩久久免费电影| 亚洲午夜未删减在线观看| 日韩一区二区av| 国产成人在线精品| 日韩激情av在线播放| 亚洲成人999| 精品久久久久久久久久久| 富二代精品短视频| 精品国内产的精品视频在线观看| 日韩亚洲一区二区| 国产精品久久久久影院日本| 91在线高清免费观看| 色综合视频网站| 日韩在线观看免费| 久久精品美女视频网站| 久久亚洲精品毛片| 欧美性高潮在线| 亚洲最大成人网色| 久久久噜噜噜久久| 亚洲成人a**站| 午夜精品久久17c| 久久在线免费视频| 久久香蕉国产线看观看av| 亚洲精品久久久久| 欧美日韩在线观看视频| 欧洲日韩成人av| 91精品久久久久久久久久另类| 一区二区国产精品视频| 久久久在线免费观看| 超碰97人人做人人爱少妇| 日本韩国欧美精品大片卡二| 97在线观看视频国产| 久久精品夜夜夜夜夜久久| 欧美成人精品一区二区三区| 日韩精品免费一线在线观看| 色七七影院综合| 国产亚洲精品美女久久久| 日韩在线观看网站| 国产亚洲精品91在线| 国产亚洲欧美aaaa| 国产欧美日韩精品专区| 久99九色视频在线观看| 亚洲精品资源美女情侣酒店| 亚洲视频综合网| 欧洲日本亚洲国产区| 日韩av理论片| 国产精品看片资源| 国产精品自拍偷拍视频| 国产精品久久久久久久久久久久| 亚洲色图狂野欧美| 2019亚洲男人天堂| 日韩av影片在线观看| 国产一区二区三区丝袜| 国产香蕉一区二区三区在线视频| 777午夜精品福利在线观看| 欧美性xxxxx| 国产精品99一区| 亚洲奶大毛多的老太婆| 在线观看日韩欧美| 538国产精品视频一区二区| 91亚洲国产成人精品性色| 97久久精品人搡人人玩| 亚洲区一区二区| 欧美福利视频网站| 欧美一区二粉嫩精品国产一线天| 日本国产欧美一区二区三区| 欧美精品18videos性欧| 成人动漫网站在线观看| 国产欧美一区二区三区四区| 欧美激情乱人伦一区| 国产主播喷水一区二区| 国产在线久久久| 黑人巨大精品欧美一区二区免费| …久久精品99久久香蕉国产| 久久精品国产一区二区三区| 日本国产高清不卡| 亚洲免费人成在线视频观看| 欧美大片在线免费观看| 欧美日韩激情视频8区| 国产97在线播放| 色综合亚洲精品激情狠狠| 91久久精品国产91久久| 91精品国产91久久久| 欧美成人性色生活仑片| 亚洲成人a**站| 久久夜色精品国产亚洲aⅴ| 久久av红桃一区二区小说| 亚洲久久久久久久久久久| 欧美放荡办公室videos4k| 日韩经典中文字幕在线观看| 日韩久久精品成人| 久久精品电影网站| 国产一区二区三区视频免费| 日韩av网址在线观看| 5566成人精品视频免费| 亚洲精品videossex少妇| 久久99视频免费| 欧美激情二区三区| 国产日韩欧美在线观看| 91欧美激情另类亚洲| 精品偷拍各种wc美女嘘嘘| 亚洲国产高清福利视频| 亚洲国产日韩精品在线| 欧美日韩激情美女| 精品视频在线观看日韩| 97精品在线视频| 中文字幕亚洲欧美日韩在线不卡| 欧美在线激情网| 国产精品成人av在线| 一区二区三区四区在线观看视频| 91国产在线精品| 国产精品女主播视频| 在线视频精品一| 在线亚洲男人天堂| 中文字幕九色91在线| 欧美大全免费观看电视剧大泉洋| 国产欧美一区二区白浆黑人| 午夜精品免费视频| 色www亚洲国产张柏芝| 国产视频自拍一区| 日本免费一区二区三区视频观看| 国产精品久久久久久影视| 日韩风俗一区 二区| 亚洲男人天堂古典|