精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

久久久久久久高潮| 秋霞影视一区二区三区| 亚洲欧美日韩人成在线播放| 97久草视频| 日本少妇性生活| 一区二区美女| 欧美一区二区三区视频在线观看 | 色婷婷av一区二区三区之红樱桃| 国产精品日韩精品欧美精品| 最近免费中文字幕视频2019| 中文字幕一区二区三区人妻在线视频 | 水蜜桃色314在线观看| 可以在线观看的黄色| 狠狠狠色丁香婷婷综合久久五月| 国模吧一区二区| 亚洲激情图片网| 欧美a大片欧美片| 欧美日韩一区二区三区四区五区| 少妇大叫太大太粗太爽了a片小说| 亚洲av成人精品一区二区三区在线播放 | 国产精品青草久久| 精品国产一区二区三区免费| 羞羞色院91蜜桃| 日韩亚洲国产欧美| 久久精品国产成人精品| 超碰97人人干| 大奶一区二区三区| 在线成人免费观看| 北条麻妃av高潮尖叫在线观看| 神马午夜伦理不卡| 国产精品日产欧美久久久久| 精品免费二区三区三区高中清不卡| 国产一区二区自拍视频| 老司机精品视频网站| 久久久久久午夜| 五月天av网站| 久久国产小视频| 亚洲性日韩精品一区二区| 性猛交╳xxx乱大交| 亚洲国产精选| 欧美色倩网站大全免费| 成人免费毛片网| 国产高清自产拍av在线| 一区二区三区在线影院| 中文字幕剧情在线观看一区| 国产中文字幕在线| 久久综合中文字幕| 狠狠综合久久av| 蜜桃视频污在线观看| 国产一区二区三区免费播放 | 最新国产精品精品视频| 欧美日韩国产美女| 91视频免费版污| 在线看欧美视频| 一本久道中文字幕精品亚洲嫩| r级无码视频在线观看| 午夜成年人在线免费视频| 亚洲女同一区二区| 欧美a级黄色大片| 国产在线看片| 亚洲久草在线视频| 国产女教师bbwbbwbbw| 三级网站视频在在线播放| 亚洲免费观看高清完整版在线观看熊| 黄色免费高清视频| dy888亚洲精品一区二区三区| 日韩美女视频一区| 亚洲五码在线观看视频| 黄色大片在线| 亚洲成a天堂v人片| 青青艹视频在线| 怡红院成人在线| 欧美日韩亚洲国产综合| 911福利视频| 欧美日韩黄色| 精品成人佐山爱一区二区| 欧美xxxxx少妇| 小说区图片区色综合区| 亚洲天堂久久av| 九九热久久免费视频| 国产精品久久久久久麻豆一区软件 | aaaa黄色片| 亚洲8888| 精品国产拍在线观看| 中文字幕av久久爽av| 在线视频精品| 国产日本欧美视频| 国产黄色av网站| av电影在线观看不卡| 日本最新一区二区三区视频观看| 午夜不卡视频| 亚洲成人精品影院| 国产免费又粗又猛又爽| 日韩精品成人| 亚洲欧美成人网| 中文字幕在线观看二区| 国产一区美女| 国产精品草莓在线免费观看| 99久久婷婷国产一区二区三区| 暴力调教一区二区三区| 亚洲欧美日韩国产yyy| 日韩特级毛片| 欧美艳星brazzers| 国产乱国产乱老熟300部视频| 自拍亚洲一区| 免费成人高清视频| 黄色一级片免费在线观看| 日韩黄色在线观看| av一区二区三区四区电影| 久久久久久久久亚洲精品| 一区二区成人在线视频| 少妇激情一区二区三区| jizz性欧美2| 色阁综合伊人av| 少妇一级淫片免费放中国| 久久丁香综合五月国产三级网站| 国产区一区二区三区| 91大神在线网站| 精品国产91久久久| 国产91在线免费观看| 国产一区二区三区天码| 欧美激情亚洲另类| 97在线公开视频| 中文字幕国产一区| 免费高清在线观看免费| 91精品尤物| 精品国模在线视频| 人妻中文字幕一区二区三区| 99久久99久久久精品齐齐| 日本精品免费视频| 久久久久久久性潮| 亚洲少妇中文在线| 久久中文字幕免费| 成人av网站大全| 欧美中日韩在线| 日本中文字幕视频一区| 伊人伊成久久人综合网小说| 日韩欧美大片在线观看| 成人免费精品视频| 久久久无码中文字幕久...| 国产精品久久久久久久久免费高清 | 日韩视频在线观看一区二区三区| 国产精品亚洲二区| 人体精品一二三区| 色视频在线观看| 欧美日韩精品国产| 色呦呦一区二区| 99在线精品视频在线观看| 不卡视频一区| 国产精品69xx| 精品欧美一区二区在线观看 | 色婷婷香蕉在线一区二区| 日韩无码精品一区二区| 伊人精品视频| 国产有色视频色综合| 19禁羞羞电影院在线观看| 亚洲精品720p| 五月天婷婷久久| 91老司机福利 在线| 凹凸国产熟女精品视频| 性欧美lx╳lx╳| 情事1991在线| 岛国大片在线观看| 精品视频999| 香蕉成人在线视频| 国产在线精品免费av| 大地资源网在线观看免费官网| 韩国三级大全久久网站| 久久99精品久久久久久噜噜| 蜜桃在线一区二区| 一本色道久久综合亚洲91| 亚洲av无码国产精品麻豆天美 | 激情成人在线观看| 国内久久视频| 欧美高清性xxxxhd| 岛国精品在线| 欧美伦理视频在线观看| www一区二区三区| 欧美精品少妇videofree| 精品毛片一区二区三区| 亚洲成在人线免费| 国内精品久久99人妻无码| 日韩制服丝袜av| 自拍偷拍一区二区三区| 丁香5月婷婷久久| 国产成人拍精品视频午夜网站| √新版天堂资源在线资源| 欧美一区二区三区的| 欧美三级韩国三级日本三斤在线观看| 久久免费偷拍视频| 爱豆国产剧免费观看大全剧苏畅 | 99精品在线播放| 欧美激情一区二区三区蜜桃视频| 手机在线视频一区| 亚洲在线国产日韩欧美| 亚洲国产一区二区三区在线播| 人人爱人人干婷婷丁香亚洲| 欧美一区三区三区高中清蜜桃| 婷婷激情在线| 精品av综合导航| 懂色av蜜臀av粉嫩av喷吹| 一区二区三区不卡视频| 免费看污片的网站| 成人激情小说乱人伦| 簧片在线免费看| 激情婷婷亚洲| 一区二区成人国产精品| 牛牛影视一区二区三区免费看| 国产精品麻豆va在线播放| 欧美videos另类精品| 在线观看国产欧美| 好吊视频一二三区| 欧美日韩成人一区二区| 国内自拍视频在线播放| 亚洲精品成人精品456| 99久久精品免费视频| 99视频在线精品| 日韩欧美色视频| 美女视频第一区二区三区免费观看网站 | 欧美性猛交乱大交| 秋霞国产午夜精品免费视频| 六月丁香激情网| 国内精品美女在线观看| 中文字幕av日韩精品| 精品久久久中文字幕| 精品国产乱码一区二区三区四区| 一区二区在线视频观看| 91精品国产综合久久香蕉922| 裤袜国产欧美精品一区| 高清一区二区三区四区五区| 羞羞的视频在线观看| 久久精品在线播放| 国产毛片在线看| 亚洲老头老太hd| 亚洲人午夜射精精品日韩| 日韩欧美123| 国产成人精品一区二三区四区五区 | 中文字幕欧美日韩va免费视频| 日日夜夜精品免费| 欧美成人精品1314www| 精品久久久久久亚洲综合网站| 欧美日韩一级片网站| japanese国产在线观看| 91国产福利在线| 91精品国产高清一区二区三密臀| 亚洲成a人v欧美综合天堂| 青草草在线视频| 亚洲精品成人精品456| 少妇久久久久久被弄高潮| 日韩理论片网站| 日本激情视频一区二区三区| 国产精品乱人伦中文| 国产一区二区三区视频播放| 亚洲国产成人在线| 麻豆视频免费在线播放| 国产精品视频一区二区三区不卡| 能直接看的av| 国产精品护士白丝一区av| 国产视频123区| **性色生活片久久毛片| 国产高潮国产高潮久久久91| 一区二区三区中文字幕电影 | 五十路六十路七十路熟婆| 成人h版在线观看| 国产麻豆xxxvideo实拍| 久久综合色婷婷| 国产jjizz一区二区三区视频| 亚洲国产精品国自产拍av| 很污很黄的网站| 日韩美女视频一区二区| 国产在线成人精品午夜| 精品国产成人av| 91麻豆精品在线| 欧美片在线播放| 亚洲AV无码成人片在线观看| 亚洲国产成人久久综合一区| 欧洲亚洲精品视频| 伊人伊人伊人久久| av网站导航在线观看免费| 久久免费视频这里只有精品| 亚洲免费福利| 91精品在线观| 欧美顶级毛片在线播放| 五月天丁香综合久久国产| 欧美在线视屏| 黄色片视频在线免费观看| 男人的j进女人的j一区| 国产在线a视频| 久久夜色精品国产噜噜av| 亚洲综合久久av一区二区三区| 亚洲一区二区三区小说| 99久久久无码国产精品免费蜜柚| 51精品秘密在线观看| 无套内谢的新婚少妇国语播放| 中文字幕亚洲二区| h片在线观看| 国产精品自拍小视频| 国产成人aa在线观看网站站| 五月天久久狠狠| 亚洲激精日韩激精欧美精品| 污污动漫在线观看| av电影在线观看一区| 成人在线观看免费完整| 色综合天天综合色综合av| 国产黄a三级三级看三级| 国产一区二区三区视频在线观看| 性欧美1819sex性高清大胸| 日韩av成人在线观看| 国产厕拍一区| 国产又粗又长又爽视频| 免费成人美女在线观看| 亚洲国产精品成人综合久久久| 亚洲欧美国产三级| 欧美一区二区三区久久久| 欧美va在线播放| 黄色一级大片在线免费看产| 日韩av色在线| 久久久亚洲欧洲日产| 8x8x华人在线| 另类小说欧美激情| 熟女俱乐部一区二区| 亚洲超碰精品一区二区| 999国产精品视频免费| 中文字幕一精品亚洲无线一区| 日本三级一区| 国产精品乱码| 午夜欧美视频| 日本成人xxx| 成人免费在线视频| 中文在线字幕免费观| 亚洲美女av在线| 欲香欲色天天天综合和网| 98国产高清一区| 午夜精品剧场| 搡的我好爽在线观看免费视频| 中文字幕不卡的av| 在线观看你懂的网站| 亚洲欧美国产另类| 最近高清中文在线字幕在线观看1| 高清日韩一区| 亚洲国产1区| 亚洲av成人精品一区二区三区| 亚洲一区视频在线| 亚洲免费不卡视频| 欧美精品福利在线| 伊色综合久久之综合久久| 日韩亚洲欧美一区二区| 国产精品自拍一区| 欧美日韩在线国产| 欧美成人一级视频| 91豆花视频在线播放| 国产欧美日韩一区二区三区| 精品1区2区3区4区| yy1111111| 欧美视频在线免费| 黄色的视频在线免费观看| 国产激情久久久久| 精品国产不卡| 三上悠亚在线一区| 18欧美乱大交hd1984| 999免费视频| 欧美黑人xxxx| 欧美福利在线播放网址导航| 午夜精品久久久内射近拍高清 | 日韩精品一区二区在线观看| 曰本三级在线| 国产亚洲第一区| 欧美综合国产| 中文字幕黄色网址| 91精品国产免费| 91超碰在线免费| 日韩亚洲不卡在线| 国内成+人亚洲+欧美+综合在线| 久草视频手机在线| 精品国产露脸精彩对白| 周于希免费高清在线观看| 婷婷久久伊人| 国产成人精品网址| 日韩免费视频一区二区视频在线观看 | 国产欧美激情视频| 亚洲国产综合人成综合网站| 三区在线观看| 91精品久久久久久久久久| 国内综合精品午夜久久资源| 久久亚洲AV成人无码国产野外| 欧美日韩在线观看一区二区| 污视频网站在线免费| 久热国产精品视频一区二区三区| 日本中文一区二区三区| 欧美日韩精品亚洲精品| 精品亚洲精品福利线在观看| 日韩大陆av| 久久黄色片视频| 中文字幕在线观看不卡| 天天色综合av| 成人黄色av免费在线观看| 99伊人成综合| 精品自拍偷拍视频| 亚洲欧美在线免费| 91九色鹿精品国产综合久久香蕉|