国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Google App Engine的Java持久性與數據存儲

開發 開發工具
本文是Rick Hightower的Google App Engine介紹系列的第三部分,他將在這篇文章中講述有關持久層和關系中一些需要學習的知識。

本文繼續介紹Google App Engine for Java。這篇講述持久性和關系。

Google App Engine for Java 力求為可伸縮的 Web 應用程序成功地編寫一個持久層,可這個目標的達成情況又如何呢?在本文中,我將概述 App Engine for Java 的持久性框架,從而結束本系列文章。該框架以 Java Data Objects(JDO)和 Java Persistence API(JPA)為基礎。盡管在剛剛出現時前景良好,但是 App Engine 的基于 Java 的持久性目前存在一些嚴重的缺陷,我將對此進行解釋和演示。您將學習 App Engine for Java 持久性是如何運作以及有著哪些挑戰,還將學習在使用面向 Java 開發人員的 Google 云平臺時,您具有哪些持久性選擇。

在閱讀本文并遍覽這些示例時,您要牢記這樣的事實:現在的 App Engine for Java 是一個預覽 版?;?Java 的持久性目前也許并不是您所希望或者需要的全部,可能并且應該會在未來發生變化。現如今,使用 App Engine for Java 進行可伸縮的、數據密集型的 Java 應用程序開發不合適膽小者或者保守派,這就是我在撰寫本文時所學到的。這更像跳入了游泳池的最深處:看不到任何救生員,項目要沉下去還是往前游,取決于您自己。

注意,本文中的示例應用程序以 第 2 部分 中開發的聯系人管理應用程序為基礎。您需要構建該應用程序,確保它是可運行的,這樣才能繼續學習本文的示例。

基礎知識和抽象泄漏(leaky abstraction)

與原始的 Google App Engine 一樣,App Engine for Java 依靠 Google 的內部基礎設施,實現可伸縮的應用程序開發的 Big Three:分布、復制和負載均衡。由于使用的是 Google 基礎設施,因此所有神奇的地方大都發生在后臺,可以通過 App Engine for Java 的基于標準的 API 獲得。數據存儲接口是以 JDO 和 JPA 為基礎的,而它們自身又是以開源的 DataNucleus 項目為基礎。AppEngine for Java 還提供了一個低級別的適配器 API,用來直接處理基于 Google 的 BigTable 實現的 App Engine for Java 數據存儲(要了解更多有關 BigTable 的信息,請參見 第 1 部分)。

然而,App Engine for Java 數據持久性并不像純 Google App Engine 中的持久性那樣簡單。由于 BigTable 不是一個關系數據庫,JDO 和 JPA 的接口出現了一些抽象泄漏。例如,在 App Engine for Java 中,您無法進行那些執行連接的查詢。您可以在 JPA 和 JDO 間設置關系,但它們只能用來持久化關系。并且在持久化對象時,如果它們在相同的實體群中,那么它們只能被持久化到相同的原子事務中。根據慣例,具有所有權的關系位于與父類相同的實體群中。相反,不具有所有權的關系可以在不同的實體群中。

重新考慮數據規范化

要使用 App Engine 的可伸縮的數據存儲,需要重新考慮有關規范化數據的優點的教導。當然,如果您在真實的環境中工作了足夠長的時間,那么,您可能已經為了追求性能而犧牲過規范化了。區別在于,在處理 App Engine 數據存儲時,您必須盡早且經常進行反規范化。反規范化 不再是一個忌諱的字眼,相反,它是一個設計工具,您可以把它應用在 App Engine for Java 應用程序的許多方面。

當您嘗試把為 RDBMS 編寫的應用程序移植到 App Engine for Java 時,App Engine for Java 的持久性泄漏的主要缺陷就會顯露出來。App Engine for Java 數據存儲并不是關系數據庫的臨時替代物,因此,要把您對 App Engine for Java 所做的工作移植到 RDBMS 端口并不容易。采用現有的模式并把它移植到數據存儲中,這種場景則更為少見。如果您決定把一個遺留的 Java 企業應用程序移植到 App 引擎中,建議您要小心謹慎,并進行備份分析。Google App Engine 是一個針對專門為它設計的應用程序的平臺。Google App Engine for Java 支持 JDO 和 JPA,這使得這些應用程序能夠被移植回更傳統的、未進行規范化的企業應用程序。

關系的問題

App Engine for Java 目前的預覽版的另外一個缺點是它對關系的處理。為了創建關系,現在您必須對 JDO 使用 App Engine for Java 特有的擴展。假設鍵是在 BigTable 的工件的基礎上生成 — 也就是說,“主鍵” 將父對象鍵編碼到其所有子鍵中 — 您將不得不在一個非關系數據庫中管理數據。另外一個限制是持久化數據。如果您使用非標準的 AppEngine for Java Key 類,事情將會變得復雜。首先,把模型移植到 RDBMS 時,如何使用非標準 Key? 其次,由于無法使用 GWT 引擎轉換 Key 類,因此,任何使用這個類的模型對象都無法被作為 GWT 應用程序的一部分進行使用。

當然,撰寫這篇文章時,Google App Engine for Java 還是純粹的預覽模式,沒有到發布的最佳時間。學習 JDO 中的關系文檔(很少,而且包含一些不完整的示例)時,這點就變得顯而易見了。

App Engine for Java 開發包提供了一系列的示例程序。許多示例都使用 JDO,沒有一個使用 JPA。這些示例中沒有一個示例(包括一個名為 jdoexamples 的示例)演示了關系,即使是簡單的關系。相反,所有的示例都只使用一個對象把數據保存到數據存儲中。Google App Engine for Java 討論組 充斥著有關如何使簡單關系起作用的問題,但卻鮮有答案。很顯然,有些開發人員有辦法使其起作用,但是實現起來都很困難,而且遇到了一些復雜情況。

App Engine for Java 中的關系的底線是,無需從 JDO 或 JPA 獲得大量支持就能夠管理它們。 Google 的 BigTable 是一種已經經過檢驗的技術,可用來生成可伸縮的應用程序,然而,您還可以在此基礎上進行構建。在 BigTable 上進行構建,您就不必處理還不完善的 API 層面。另一方面,您只要處理一個較低級別的 API。

#p#

App Engine for Java 中的 Java Data Objects

把傳統的 Java 應用程序移植到 App Engine for Java 中,甚至是給出關系挑戰,這些可能都沒有什么意義,然而,持久性場景還是存在的,這時使用這個平臺就有意義了。我將使用一個可行的示例來結束本文,您將體驗 App Engine for Java 持久性是如何工作的。我們將以 第 2 部分 中建立的聯系人管理應用程序為基礎,介紹如何添加支持,以使用 App Engine for Java 數據存儲工具持久化 Contact 對象。

在前面的文章中,您創建了一個簡單的 GWT GUI,對 Contact 對象進行 CRUD 操作。您定義了簡單的接口,如清單 1 所示:

清單 1. 簡單的 ContactDAO 接口
				
package gaej.example.contact.server;

import java.util.List;

import gaej.example.contact.client.Contact;

public interface ContactDAO {
	void addContact(Contact contact);
	void removeContact(Contact contact);
	void updateContact(Contact contact);
	List<Contact> listContacts();
}

接下來,創建一個模擬版本,與內存集合中的數據進行交互,如清單 2 所示:

清單 2. 模擬 DAO 的 ContactDAOMock
				
package gaej.example.contact.server;

import gaej.example.contact.client.Contact;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ContactDAOMock implements ContactDAO {

	Map<String, Contact> map = new LinkedHashMap<String, Contact>();
	
	{
		map.put("rhightower@mammatus.com", new Contact("Rick Hightower", 
                                 "rhightower@mammatus.com", "520-555-1212"));
		map.put("scott@mammatus.com", new Contact("Scott Fauerbach", 
                                 "scott@mammatus.com", "520-555-1213"));
		map.put("bob@mammatus.com", new Contact("Bob Dean", 
                                 "bob@mammatus.com", "520-555-1214"));

	}
	
	public void addContact(Contact contact) {
		String email = contact.getEmail();
		map.put(email, contact);
	}

	public List<Contact> listContacts() {
		return Collections.unmodifiableList(new ArrayList<Contact>(map.values()));
	}

	public void removeContact(Contact contact) {
		map.remove(contact.getEmail());
	}

	public void updateContact(Contact contact) {		
		map.put(contact.getEmail(), contact);
	}

}

現在,使用與 Google App Engine 數據存儲交互的應用程序替換模擬實現,看看會發生什么。在這個示例中,您將使用 JDO 持久化 Contact 類。使用 Google Eclipse Plugin 編寫的應用程序已經擁有了使用 JDO 所需的所有庫。它還包含了一個 jdoconfig.xml 文件,因此,一旦對 Contact 類進行了注釋,您就已經準備好開始使用 JDO。

清單 3 顯示擴展后的 ContactDAO 接口,可使用 JDO API 進行持久化、查詢、更新和刪除對象:

清單 3. 使用 JDO 的 ContactDAO
				
package gaej.example.contact.server;

import gaej.example.contact.client.Contact;

import java.util.List;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

public class ContactJdoDAO implements ContactDAO {
	private static final PersistenceManagerFactory pmfInstance = JDOHelper
			.getPersistenceManagerFactory("transactions-optional");

	public static PersistenceManagerFactory getPersistenceManagerFactory() {
		return pmfInstance;
	}

	public void addContact(Contact contact) {
		PersistenceManager pm = getPersistenceManagerFactory()
				.getPersistenceManager();
		try {
			pm.makePersistent(contact);
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Contact> listContacts() {
		PersistenceManager pm = getPersistenceManagerFactory()
				.getPersistenceManager();
		String query = "select from " + Contact.class.getName();
		return (List<Contact>) pm.newQuery(query).execute();
	}

	public void removeContact(Contact contact) {
		PersistenceManager pm = getPersistenceManagerFactory()
				.getPersistenceManager();
		try {
			pm.currentTransaction().begin();

			// We don't have a reference to the selected Product.
			// So we have to look it up first,
			contact = pm.getObjectById(Contact.class, contact.getId());
			pm.deletePersistent(contact);

			pm.currentTransaction().commit();
		} catch (Exception ex) {
			pm.currentTransaction().rollback();
			throw new RuntimeException(ex);
		} finally {
			pm.close();
		}
	}

	public void updateContact(Contact contact) {
		PersistenceManager pm = getPersistenceManagerFactory()
				.getPersistenceManager();
		String name = contact.getName();
		String phone = contact.getPhone();
		String email = contact.getEmail();

		try {
			pm.currentTransaction().begin();
			// We don't have a reference to the selected Product.
			// So we have to look it up first,
			contact = pm.getObjectById(Contact.class, contact.getId());
			contact.setName(name);
			contact.setPhone(phone);
			contact.setEmail(email);
			pm.makePersistent(contact);
			pm.currentTransaction().commit();
		} catch (Exception ex) {
			pm.currentTransaction().rollback();
			throw new RuntimeException(ex);
		} finally {
			pm.close();
		}
	}

}

#p#

逐一比對方法

現在,考慮一下使用清單 3 中的每個方法時發生的情況。您將會發現,方法的名字可能是新的,但它們的動作大部分情況下都應該感到熟悉。

首先,為了獲取 PersistenceManager,創建了一個靜態的 PersistenceManagerFactory。如果您以前使用過 JPA,PersistenceManager 與 JPA 中的 EntityManager 很相似。如果您使用過 Hibernate,PersistenceManager 與 Hibernate Session 很相似?;旧?,PersistenceManager 是 JDO 持久性系統的主接口。它代表了與數據庫的會話。getPersistenceManagerFactory() 方法返回靜態初始化的 PersistenceManagerFactory,如清單 4 所示:

清單 4. getPersistenceManagerFactory() 返回 PersistenceManagerFactory
				
private static final PersistenceManagerFactory pmfInstance = JDOHelper
		.getPersistenceManagerFactory("transactions-optional");

public static PersistenceManagerFactory getPersistenceManagerFactory() {
	return pmfInstance;
}

addContact() 方法把新的聯系人添加到數據存儲中。為了做到這點,需要創建一個 PersistenceManager 實例,然后,調用 PersistenceManagermakePersistence() 方法。makePersistence() 方法采用臨時的 Contact 對象(用戶將在 GWT GUI 中填充),并且使其成為一個持久的對象。所有這些如清單 5 所示:


清單 5. addContact()
				
public void addContact(Contact contact) {
	PersistenceManager pm = getPersistenceManagerFactory()
			.getPersistenceManager();
	try {
		pm.makePersistent(contact);
	} finally {
		pm.close();
	}
}

注意在清單 5 中,persistenceManager 是如何被封入在 finally 塊中。這確保能夠把與 persistenceManager 關聯的資源清除干凈。

如清單 6 所示,listContact() 方法從它所查找的 persistenceManager 中創建一個查詢對象。它調用了 execute() 方法,從數據存儲中返回 Contact 列表。


清單 6. listContact()
				
@SuppressWarnings("unchecked")
public List<Contact> listContacts() {
	PersistenceManager pm = getPersistenceManagerFactory()
			.getPersistenceManager();
	String query = "select from " + Contact.class.getName();
	return (List<Contact>) pm.newQuery(query).execute();
}

在從數據存儲中刪除聯系人之前,removeContact() 通過 ID 查找聯系人,如清單 7 所示。它必須這么做,而不僅僅是把聯系人直接刪除,這是因為來自 GWT GUI 的 Contact 對 JDO 一無所知。在刪除前,您必須獲得與 PersistenceManager 緩存關聯的 Contact。


清單 7. removeContact()
				
public void removeContact(Contact contact) {
	PersistenceManager pm = getPersistenceManagerFactory()
			.getPersistenceManager();
	try {
		pm.currentTransaction().begin();

		// We don't have a reference to the selected Product.
		// So we have to look it up first,
		contact = pm.getObjectById(Contact.class, contact.getId());
		pm.deletePersistent(contact);

		pm.currentTransaction().commit();
	} catch (Exception ex) {
		pm.currentTransaction().rollback();
		throw new RuntimeException(ex);
	} finally {
		pm.close();
	}
}

清單 8 中的 updateContact() 方法與 removeContact() 方法類似,用來查找 Contact。然后,updateContact() 方法從 Contact 中復制屬性。這些屬性被當作實參(Argument)傳送到 Contact,后者由持久性管理器查找。使用 PersistenceManager 檢查所查找的對象發生的變化。如果對象發生了變化,當事務進行提交時,這些變化會被 PersistenceManager 刷新到數據庫。


清單 8. updateContact()
				
public void updateContact(Contact contact) {
	PersistenceManager pm = getPersistenceManagerFactory()
			.getPersistenceManager();
	String name = contact.getName();
	String phone = contact.getPhone();
	String email = contact.getEmail();

	try {
		pm.currentTransaction().begin();
		// We don't have a reference to the selected Product.
		// So we have to look it up first,
		contact = pm.getObjectById(Contact.class, contact.getId());
		contact.setName(name);
		contact.setPhone(phone);
		contact.setEmail(email);
		pm.makePersistent(contact);
		pm.currentTransaction().commit();
	} catch (Exception ex) {
		pm.currentTransaction().rollback();
		throw new RuntimeException(ex);
	} finally {
		pm.close();
	}
}

#p#

對象持久性注釋

為了使 Contact 能夠具有持久性,必須把它識別為一個具有 @PersistenceCapable 注釋的可持久性對象。然后,需要對它所有的可持久性字段進行注釋,如清單 9 所示:


清單 9. Contact 具有可持久性
				
package gaej.example.contact.client;

import java.io.Serializable;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Contact implements Serializable {

	private static final long serialVersionUID = 1L;
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Long id;
	@Persistent
	private String name;
	@Persistent
	private String email;
	@Persistent
	private String phone;

	public Contact() {

	}

	public Contact(String name, String email, String phone) {
		super();
		this.name = name;
		this.email = email;
		this.phone = phone;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

}

通過面向對象的編程和接口設計原則,您只需使用新的 ContactJdoDAO 替代原始的 ContactDAOMock。然后 GWT GUI 無需任何修改就可處理 JDO。

最后,在這種替換中,真正改變 的是 DAO 在服務中被實例化的方式。如清單 10 所示:


清單 10. RemoteServiceServlet
				
public class ContactServiceImpl extends RemoteServiceServlet implements ContactService {
	private static final long serialVersionUID = 1L;
	//private ContactDAO contactDAO = new ContactDAOMock();
	private ContactDAO contactDAO = new ContactJdoDAO();
...

結束語

在這篇由三部分組成的文章中,介紹了 Google App Engine for Java 目前為持久性提供的支持,這是交付可伸縮應用程序的基礎??偟慕Y論令人失望,但是要注意這是一個正在發展中的平臺。為 App Engine for Java 預覽版編寫的應用程序被連接到 App Engine 的持久性基礎設施,即使是用 JDO 或 JPA 編寫。App Engine for Java 預覽版幾乎沒有為它的持久性框架提供任何文檔,而且 App Engine for Java 提供的示例幾乎無法演示即使是最簡單的關系。

即使 JDO 和 JPA 實現已經完全成熟,目前您仍然不可能編寫一個 App Engine for Java 應用程序并輕松地把它移植到一個基于 RDBMS 的企業應用程序。要使移植能夠起作用,至少要編寫大量的代碼。

我希望持久性能隨著時間的推移而成熟起來。如果現在必須使用 App Engine for Java,您可能需要繞過 Java API,直接編寫低級別的 Datastore API。使用 App Engine for Java 平臺是可能的,但是,如果習慣了使用 JPA 和/或 JDO,那么將出現一條學習曲線,因為存在本文前面描述的抽象泄漏,并且目前的功能要么還無法正常運行,要么還沒有進行很好的文檔記錄。

責任編輯:yangsai 來源: IBMDW
相關推薦

2013-07-09 10:18:58

VDI虛擬化

2022-10-27 08:00:32

DockerAWS云容器

2021-05-25 10:20:31

Python持久性編程語言

2023-12-08 08:26:05

數據存儲持久性

2019-09-06 09:50:52

云存儲硬盤云服務

2009-09-27 09:55:38

Hibernate持久

2009-09-02 11:34:09

Google App

2021-01-22 10:40:08

Linux文件內存

2009-09-23 15:25:08

Hibernate 3

2009-06-26 16:32:22

App Engine文檔存儲文檔搜索

2009-04-13 15:48:54

Google AppJavaSun

2009-04-08 16:47:11

GoogleApp EngineJava

2009-04-09 08:54:07

App EnginegoogleJava

2009-04-09 09:53:43

GoogleAppEngineJava

2012-08-01 14:12:45

IBMdW

2009-09-10 10:11:44

Google App Java開發2.0

2014-06-05 14:41:05

亞馬遜AWS

2021-06-02 08:00:00

MOSH開源工具

2009-07-14 09:25:43

Google App GAEJava SDK 1.

2013-07-30 12:29:19

Google App Google技術Engine
點贊
收藏

51CTO技術棧公眾號

欧美精品二区三区四区免费看视频| 久久影院理伦片| 91中文在线| 最新国产成人在线观看| 亚洲精品无人区| 五月天激情综合网| 91国产精品91| 在线精品国产亚洲| 久久精品中文字幕免费mv| 91福利在线免费| 91精品国产入口在线| 国产资源在线播放| 蜜臀av无码一区二区三区| 午夜久久福利| 成人久久18免费网站图片| 久久99视频| 欧洲永久精品大片ww免费漫画| 亚洲成人a级片| 曰本色欧美视频在线| 久久电影tv| 99精品桃花视频在线观看| 色狠狠久久av五月综合| 亚洲一区观看| 欧美激情www| 国产精品一二| 久久国产精品 国产精品| 欧美体内she精视频在线观看| 91精品国产自产在线观看永久| 国产日韩视频在线| 国产日产欧美a一级在线| 久久亚洲在线| 国产二区不卡| 导航艳情国产电影| 久久久精品欧美丰满| 丁香婷婷激情网| 综合网在线视频| 亚洲成人福利| 欧美一区二区三区成人| 黄色国产小视频| 久久久99免费| 成人国产亚洲精品a区天堂华泰| 激情综合网五月激情 | 伦xxxx在线| 欧美午夜久久久| 1024视频在线| 亚洲第一页在线| 欧洲精品久久久久毛片完整版| 欧美激情视频播放| 久久蜜桃av| 欧美一区二区三区四区在线观看地址 | 欧美日韩另类国产亚洲欧美一级| 最新国产在线观看| 精品亚洲一区二区| 色妞ww精品视频7777| 国产美女搞久久| 久久精品三级| 久章草在线视频| 一本久道久久综合中文字幕| 成人免费高清观看| 精品国产一区二区三区久久狼黑人| 亚洲国产欧美日韩在线观看第一区 | 69av成年福利视频| 欧美日韩亚洲一区| 成人手机在线播放| 日日夜夜精品一区| 日韩中文在线中文网在线观看| 曰本一区二区三区视频| 裸体丰满少妇做受久久99精品| 99久久精品国产一区二区三区 | 久久久不卡网国产精品二区| 欧美女优在线观看| 伊人久久大香线蕉av一区二区| 国产一区二区三区天码| 日韩av图片| 亚洲天堂久久久久久久| 黄网av在线| 日韩美女写真福利在线观看| 奇米影视一区二区三区| 黄网在线播放| 精品中文字幕久久久久久| 久久激情电影| 高清在线观看免费| 欧美日韩激情一区二区三区| 日韩精品一区二区三区中文在线| 狠狠干一区二区| 最新国产精品久久精品| 日韩大片免费观看| 亚洲在线免费视频| 久久精品视频一区| 欧美家庭影院| 91在线高清视频| 欧美激情综合五月色丁香小说| 男女羞羞视频在线观看| 成人有码在线播放| 日本一区二区在线不卡| 岛国av在线播放| 成人免费在线一区二区三区| **欧美大码日韩| 中文字幕一区二区三区在线乱码| 日本高清久久天堂| 亚洲五码在线| 日韩中文字幕视频在线| 国色天香一区二区| 日韩小视频在线| 成人欧美一区二区三区白人| 国产成人tv| 亚洲视频一区在线观看| www.51av欧美视频| 亚洲一区二区三区在线视频| av电影一区二区| av最新在线| 久久99精品久久久水蜜桃| 亚洲自拍偷拍综合| 女同一区二区三区| 成人一对一视频| 伊人青青综合网站| 精品一区二区三区的国产在线播放 | 亚洲成人av福利| 日韩精品导航| 久久久久久香蕉| 精品国产欧美成人夜夜嗨| 国产成人丝袜美腿| av有码在线观看| 色综合久久av| 欧美va亚洲va香蕉在线| 麻豆成人在线| 黄在线免费观看| 欧美精品欧美精品| 日韩视频不卡中文| 男人的天堂久久精品| 欧美人与禽性xxxxx杂性| 日韩视频在线播放| 亚洲国产精品yw在线观看| 蜜臀久久99精品久久久久宅男| 欧美hdxxxxx| 夜夜爽www精品| 亚洲人成自拍网站| 成人性生交大片免费| 日韩一级二级| 国产在线青青草| 欧美成人午夜激情在线| 国产日韩精品一区二区三区| 亚洲高清999| 国精产品999国精产品官网| 国产精品色悠悠| 欧美在线播放高清精品| 亚洲一区二区三区高清| 国产传媒在线| 久草热视频在线观看| 久久久久久久久久久网站| 亚洲三级视频在线观看| 欧美a级成人淫片免费看| 未来日记在线观看| 国产日韩三区| 亚洲国产高清高潮精品美女| 国产福利一区二区三区在线视频| 国产精品久久久久久久久久久久久久久 | 欧美性色xo影院| 国产在线日韩| 午夜av在线播放| 免费看日本毛片| 国产精品成av人在线视午夜片| 色婷婷亚洲精品| 久久福利视频一区二区| 岛国一区二区| 黑人巨大精品欧美一区二区奶水| 91嫩草国产在线观看| 欧美zozozo| 国产欧美一区二区在线| 91麻豆国产自产在线观看亚洲| 成人看片免费| 激情婷婷综合网| 999国内精品视频在线| 亚洲国模精品一区| 国产精品嫩草影院av蜜臀| 成人看的视频| а√天堂中文在线资源8| 欧美亚洲日本在线观看| 国产日韩欧美一二三区| 亚洲国产精彩中文乱码av在线播放| 国产日韩欧美高清| 亚洲大胆视频| 精品一区二区三区中文字幕| 精品欧美不卡一区二区在线观看 | 亚洲成人中文字幕| 国产偷国产偷精品高清尤物| 天天综合亚洲| 欧美aa视频| 天天射综合网站| 九一免费在线观看| 成人免费观看a| 最新亚洲国产精品| 91激情五月电影| 国产日韩欧美综合一区| 国产欧美一级| 午夜精品福利影院| 二区三区不卡| av在线资源站| 成年免费网站| 日韩黄色短视频|