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

Google App Engine的Java持久性與數(shù)據(jù)存儲

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

本文繼續(xù)介紹Google App Engine for Java。這篇講述持久性和關(guān)系。

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

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

注意,本文中的示例應(yīng)用程序以 第 2 部分 中開發(fā)的聯(lián)系人管理應(yīng)用程序?yàn)榛A(chǔ)。您需要構(gòu)建該應(yīng)用程序,確保它是可運(yùn)行的,這樣才能繼續(xù)學(xué)習(xí)本文的示例。

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

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

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

重新考慮數(shù)據(jù)規(guī)范化

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

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

關(guān)系的問題

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

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

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

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

#p#

App Engine for Java 中的 Java Data Objects

把傳統(tǒng)的 Java 應(yīng)用程序移植到 App Engine for Java 中,甚至是給出關(guān)系挑戰(zhàn),這些可能都沒有什么意義,然而,持久性場景還是存在的,這時(shí)使用這個平臺就有意義了。我將使用一個可行的示例來結(jié)束本文,您將體驗(yàn) App Engine for Java 持久性是如何工作的。我們將以 第 2 部分 中建立的聯(lián)系人管理應(yīng)用程序?yàn)榛A(chǔ),介紹如何添加支持,以使用 App Engine for Java 數(shù)據(jù)存儲工具持久化 Contact 對象。

在前面的文章中,您創(chuàng)建了一個簡單的 GWT GUI,對 Contact 對象進(jìn)行 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();
}

接下來,創(chuàng)建一個模擬版本,與內(nèi)存集合中的數(shù)據(jù)進(jìn)行交互,如清單 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);
	}

}

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

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

清單 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#

逐一比對方法

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

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

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

public static PersistenceManagerFactory getPersistenceManagerFactory() {
	return pmfInstance;
}

addContact() 方法把新的聯(lián)系人添加到數(shù)據(jù)存儲中。為了做到這點(diǎn),需要創(chuàng)建一個 PersistenceManager 實(shí)例,然后,調(diào)用 PersistenceManagermakePersistence() 方法。makePersistence() 方法采用臨時(shí)的 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 關(guān)聯(lián)的資源清除干凈。

如清單 6 所示,listContact() 方法從它所查找的 persistenceManager 中創(chuàng)建一個查詢對象。它調(diào)用了 execute() 方法,從數(shù)據(jù)存儲中返回 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();
}

在從數(shù)據(jù)存儲中刪除聯(lián)系人之前,removeContact() 通過 ID 查找聯(lián)系人,如清單 7 所示。它必須這么做,而不僅僅是把聯(lián)系人直接刪除,這是因?yàn)閬碜?GWT GUI 的 Contact 對 JDO 一無所知。在刪除前,您必須獲得與 PersistenceManager 緩存關(guān)聯(lián)的 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 中復(fù)制屬性。這些屬性被當(dāng)作實(shí)參(Argument)傳送到 Contact,后者由持久性管理器查找。使用 PersistenceManager 檢查所查找的對象發(fā)生的變化。如果對象發(fā)生了變化,當(dāng)事務(wù)進(jìn)行提交時(shí),這些變化會被 PersistenceManager 刷新到數(shù)據(jù)庫。


清單 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 注釋的可持久性對象。然后,需要對它所有的可持久性字段進(jìn)行注釋,如清單 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;
	}

}

通過面向?qū)ο蟮木幊毯徒涌谠O(shè)計(jì)原則,您只需使用新的 ContactJdoDAO 替代原始的 ContactDAOMock。然后 GWT GUI 無需任何修改就可處理 JDO。

最后,在這種替換中,真正改變 的是 DAO 在服務(wù)中被實(shí)例化的方式。如清單 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();
...

結(jié)束語

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

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

我希望持久性能隨著時(shí)間的推移而成熟起來。如果現(xiàn)在必須使用 App Engine for Java,您可能需要繞過 Java API,直接編寫低級別的 Datastore API。使用 App Engine for Java 平臺是可能的,但是,如果習(xí)慣了使用 JPA 和/或 JDO,那么將出現(xiàn)一條學(xué)習(xí)曲線,因?yàn)榇嬖诒疚那懊婷枋龅某橄笮孤⑶夷壳暗墓δ芤催€無法正常運(yùn)行,要么還沒有進(jìn)行很好的文檔記錄。

責(zé)任編輯:yangsai 來源: IBMDW
相關(guān)推薦

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

數(shù)據(jù)存儲持久性

2019-09-06 09:50:52

云存儲硬盤云服務(wù)

2009-09-27 09:55:38

Hibernate持久

2009-09-02 11:34:09

Google App

2021-01-22 10:40:08

Linux文件內(nèi)存

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開發(fā)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技術(shù)Engine
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

自拍偷拍亚洲在线| 亚洲成人免费观看| 91精品国产综合久久久久久久久| 天天色天天综合| 免费观看性欧美大片无片| 性欧美疯狂xxxxbbbb| 一本久道久久综合中文字幕| 国产亚洲精品久久飘花| av手机天堂网| 欧美暴力喷水在线| 亚洲欧美国产视频| 911福利视频| 77thz桃花论族在线观看| 国产日韩欧美电影| 懂色中文一区二区三区在线视频| 欧美人一级淫片a免费播放| 欧美福利专区| 永久555www成人免费| av在线天堂网| 国产原创一区| 欧美午夜无遮挡| 粉嫩av一区二区三区天美传媒 | 一区二区av| 天天操天天插天天射| 激情图区综合网| 国产精品igao视频| 精品成人久久久| 自拍偷拍欧美专区| 日韩综合视频在线观看| 国产精品扒开腿做爽爽| 中文字幕久久精品一区二区| 欧美日韩在线三级| 欧美一级黄色片视频| 黄色大片在线| 一个色妞综合视频在线观看| 亚洲蜜桃在线| 国产精品一区在线看| 99精品欧美一区| 成人3d动漫一区二区三区91| 一二三区中文字幕| 日本亚洲一区二区| 日本精品视频在线播放| 国内免费精品视频| 亚洲国产国产亚洲一二三| 欧美成人免费小视频| 老司机精品免费视频| 奇米狠狠一区二区三区| 日韩电影第一页| 色婷婷精品久久二区二区密| av在线亚洲色图| 欧美成人综合网站| 韩国三级与黑人| 国产人与zoxxxx另类91| 在线成人av网站| 17c国产在线| 色综合视频一区二区三区44| 欧美日韩午夜影院| 性刺激的欧美三级视频| 全球最大av网站久久| 在线视频中文字幕一区二区| 国产福利一区视频| 成人免费毛片嘿嘿连载视频…| 在线观看国产日韩| www.com黄色片| 亚洲tv在线| 91精品国产一区二区三区蜜臀| 欧美午夜精品理论片| 精品午夜av| 欧美成人在线直播| 国产又黄又粗又猛又爽的视频 | 国产在线看一区| 亚洲一区二区三| 亚洲乱熟女一区二区| www.性欧美| 欧美人与性禽动交精品| 成人精品一区二区三区校园激情| 国产精品系列在线| 日本老太婆做爰视频| 国模雨婷捆绑高清在线| 五月天久久比比资源色| 欧美伦理片在线看| www欧美在线观看| 欧美成人午夜电影| 免费在线观看你懂的| 日韩精品dvd| 美女视频久久黄| 可以在线观看av的网站| 热久久久久久久| 亚洲字幕在线观看| 色av男人的天堂免费在线 | 久久网免费视频| 亚洲欧美日韩精品一区二区| 国产精品女主播视频| 99精品视频免费看| 2020国产成人综合网| 亚洲综合欧美日韩| 久久香蕉av| 91电影在线观看| 国产成人精品综合久久久久99| 久久中文资源| 精品国产一区av| 日韩三级视频在线播放| 久久精品99国产精品日本| 99一区二区三区| 成人av毛片| 亚洲国产wwwccc36天堂| 久久国产激情视频| 欧美日韩一本| 精品自拍视频在线观看| 蜜臀99久久精品久久久久小说| 国产美女一区二区| 日本一区二区在线视频| 2001个疯子在线观看| 欧洲av一区二区嗯嗯嗯啊| 成熟妇人a片免费看网站| av中字幕久久| 136fldh精品导航福利| 国产三级精品在线观看| 国产欧美一区二区在线观看| www.男人天堂网| 韩国精品视频在线观看 | 亚洲影院色无极综合| 国产高清自拍视频在线观看| 五月综合激情日本mⅴ| 亚洲第一成肉网| 成人羞羞动漫| 日本精品视频在线| 色在线免费视频| 亚洲第一主播视频| 亚洲国产欧美日韩在线| 久久免费大视频| 国产成人精品午夜| 日本一区视频| 偷拍日韩校园综合在线| 农村末发育av片一区二区| 天天影视天天精品| 国产精品视频地址| 成人免费高清在线播放| 91久久久免费一区二区| 怡红院一区二区| 影院欧美亚洲| 国产精品亚洲综合| 国产丝袜在线播放| 精品国产乱码久久久久久牛牛| 杨钰莹一级淫片aaaaaa播放| 精品亚洲免费视频| 亚洲欧美一二三| 国产精品xnxxcom| 精品国内自产拍在线观看| 一本色道久久综合熟妇| 日韩一区欧美小说| 一级黄色片国产| 欧美/亚洲一区| 91免费看网站| 丰满诱人av在线播放| 欧美成人精品1314www| 久操免费在线视频| 成人高清免费观看| 97成人在线免费视频| 狼人精品一区二区三区在线| 国内精品久久影院| 日本精品专区| 欧美制服丝袜第一页| 成人午夜免费影院| 国产精品911| av免费观看国产| 色婷婷久久久| 国产精品99导航| 免费观看久久久久| 日韩欧美国产精品| 日韩特黄一级片| 久久精品日韩一区二区三区| 污版视频在线观看| 亚洲精品2区| 国产精品久久久久久久小唯西川| 亚洲天堂av在线| 色偷偷亚洲男人天堂| 99久久免费国产精精品| 亚洲国产精品久久久久婷婷884 | 综合激情成人伊人| 久久精品无码专区| 久久国产88| 在线成人性视频| 澳门成人av| 国产精品999| 免费不卡av| 一区二区av在线| 午夜精品小视频| 色婷婷综合激情| 亚洲国产123| 91在线播放网址| 色一情一区二区| 一区二区三区四区五区精品视频| 视频在线99re| 岛国精品一区| 成人网在线观看| 伊人网在线播放| 欧美成人午夜影院| 国产永久av在线| 精品福利一二区| 97精品人妻一区二区三区香蕉| 午夜欧美一区二区三区在线播放| 国产精品成人无码免费| 岛国av在线一区| 在线观看国产一级片| 一二三区精品| 精品国产一区二区三区在线| 亚洲婷婷影院| 成人激情直播| 久久久久久一区二区三区四区别墅| 97久久精品国产| 国产激情在线| 一区二区三区黄色| 欧美自拍第一页| 欧美放荡的少妇| 日批视频免费在线观看| 亚洲国产精品一区二区久久恐怖片| 国产黄色录像视频| 91免费观看视频在线| 无码人妻一区二区三区免费n鬼沢| 麻豆精品久久久| 欧美一级黄色影院| 性欧美长视频| 国产黄色片免费在线观看| 91精品一区国产高清在线gif| 欧美日韩三区四区| 欧美巨大xxxx| 国产精品.com| 一区二区三区视频免费视频观看网站| 成人激情春色网| 天堂久久午夜av| 日韩女优在线播放| 三级在线观看视频| 国语自产精品视频在线看| fc2ppv国产精品久久| 久热在线中文字幕色999舞| 在线播放毛片| 日韩有码视频在线| 日本视频在线播放| 日韩最新在线视频| eeuss影院www在线观看| 一色桃子一区二区| 成年女人的天堂在线| 在线电影欧美日韩一区二区私密| 日本天堂影院在线视频| 亚洲欧美日韩精品久久亚洲区| 亚洲欧洲国产综合| 精品亚洲一区二区三区| 四虎成人免费在线| 亚洲精品视频在线播放| 黄色在线播放| 色香阁99久久精品久久久| av小片在线| 久久好看免费视频| 91精品久久| 欧美精品激情在线观看| 97蜜桃久久| 热门国产精品亚洲第一区在线| 欧美黄色网页| 国产精品三级久久久久久电影| julia一区二区三区中文字幕| 国产日韩一区在线| 国语精品视频| 成人黄视频免费| 伊人久久大香线蕉| 亚洲午夜高清视频| 欧美破处大片在线视频| heyzo国产| 免费观看在线综合| 一二三级黄色片| 成人黄色国产精品网站大全在线免费观看| 欧美做受高潮中文字幕| 久久综合999| 久久一级免费视频| 亚洲精品视频免费观看| 99热只有这里有精品| 欧美亚洲一区三区| 国产成人精品毛片| 日韩电视剧免费观看网站| 日本视频在线播放| 久久人91精品久久久久久不卡| 蜜桃精品在线| 91久久国产综合久久蜜月精品| 日韩在线黄色| 丰满女人性猛交| 国产精品美女久久久| 亚洲综合欧美激情| 成人精品国产一区二区4080| 色无极影院亚洲| 亚洲综合一二三区| 精品成人无码久久久久久| 日韩欧美你懂的| 成黄免费在线| 国模视频一区二区| 日韩护士脚交太爽了| 久久精品国产精品国产精品污 | 国产手机视频在线| 日韩电影中文字幕av| 麻豆影视在线观看_| 88xx成人精品| 欧美黄视频在线观看| 天堂精品一区二区三区| 99在线|亚洲一区二区| 亚洲欧美aaa| 2014亚洲片线观看视频免费| av激情在线观看| 欧美伊人精品成人久久综合97 | 中文字幕 视频一区| 欧美精品一区二区三区蜜臀| 瑟瑟视频在线| 国产mv免费观看入口亚洲| 99re8这里有精品热视频8在线| 一区二区精品在线| 蜜桃伊人久久| 你懂的在线观看网站| 一区二区三区丝袜| 一级片免费观看视频| 亚洲欧美制服中文字幕| 波多野结衣视频一区二区| 91精品视频在线| 日韩一区电影| 欧美日韩在线免费播放| 91丨九色porny丨蝌蚪| 久久免费在线观看视频| 日韩视频免费观看高清完整版在线观看 | 亚洲视频在线看| 国产高潮在线| 国产亚洲福利社区| 国产在线日韩| 国产chinesehd精品露脸| 自拍偷自拍亚洲精品播放| 亚洲高清视频免费观看| 亚洲男人的天堂在线| 天堂av中文在线观看| 精品免费二区三区三区高中清不卡| 欧美日韩91| 伊人五月天婷婷| 国产精品久久二区二区| 国产香蕉在线视频| 亚洲精品一区二区三区在线观看| 大片免费在线观看| 99re热精品| 亚洲精品小说| 久久久久无码精品| 亚洲影视在线观看| 欧美熟妇交换久久久久久分类 | 精品国产无码在线| 国产一区二区三区在线观看精品| 美女视频久久久| 91精品国产一区二区三区蜜臀| wwwav在线| 国产九色91| 亚洲一区图片| 久久精品视频18| 欧美三级电影一区| 国产欧美黑人| 成人高清在线观看| 亚洲一区观看| 久久久久久久久久久久久久久| 欧美亚洲国产bt| 免费黄色网址在线观看| 成人av网站观看| 男人的天堂成人在线| 我不卡一区二区| 91精品国产福利在线观看| 啪啪免费视频一区| 国外成人在线视频网站| 久久字幕精品一区| 国内毛片毛片毛片毛片毛片| 欧美一二三四区在线| 91老司机福利在线| 三区精品视频观看| 国产精品综合网| 日本一级一片免费视频| 一区二区三区高清国产| 精品一区二区三区免费看| 国产一区二区网| 1区2区3区精品视频| 好吊视频一二三区| 国产成人精品视| 欧美日韩综合| 草草影院第一页| 日韩一区二区在线观看视频| 午夜欧美激情| 中日韩在线视频| 99久久国产免费看| 91在线观看喷潮| 91成人性视频| 欧美成人日韩| 88久久精品无码一区二区毛片| 欧美一区二区网站| 人成在线免费网站| 欧美 国产 精品| 国产日韩综合av| 免费观看成年人视频| 国产精品视频自在线| 99热这里只有成人精品国产| 成年人免费视频播放| 日韩成人在线网站| 日本在线成人|