<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 78, comments - 34, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    2010-01-19 傳智播客—JPA

    Posted on 2010-01-19 23:46 長城 閱讀(580) 評論(0)  編輯  收藏

    今后三天的課程內容為:JPAEJB。我們的班型是JAVAEE精品就業班,我們學習的是JAVAEE嗎?JAVAEE是分布式企業級應用,我們之前學習的JSPServlet都是JAVAEE的內容,是基礎內容。那么JAVAEE的核心是什么?沒有學習JAVAEE的核心還算是學習過JAVAEE嗎?JAVAEE的核心是EJB

    EJB具體是做什么的?目前還不清楚,這部分內容在明天和后天會學習。今日的重點內容是JPA,什么是JPA呢?JPAEJB3中持久化部分。

     Sun引入新的JPA ORM規范出于兩個原因:其一,簡化現有Java EEJava SE應用的對象持久化的開發工作;其二,Sun希望整合對ORM技術,實現天下歸一。

      JPAEJB 3.0軟件專家組開發,作為JSR-220實現的一部分。但它不囿于EJB 3.0,你可以在Web應用、甚至桌面應用中使用。JPA的宗旨是為POJO提供持久化標準規范,由此可見,經過這幾年的實踐探索,能夠脫離容器獨立運行,方便開發和測試的理念已經深入人心了。目前Hibernate 3.2TopLink 10.1.3以及OpenJPA都提供了JPA的實現。

      JPA的總體思想和現有HibernateTopLinkJDOORM框架大體一致。

    一、搭建JPA環境

    我們之前已經學習過Hibernate,學習JPA就比較容易了。因為HibernateJPA的一種實現。

    1.創建一個普通的JAVA工程。

    2.導入“hibernate-distribution-3.3.1.GA\jpa”目錄下的所有Jar包,還有數據庫驅動包。我們使用的是MySQL

    3.在“SRC”上右鍵創建一個“META-INF”目錄,“META-INF”實際位置在classpath下。

    4.在“META-INF”目錄中添加一個“persistence.xml”文件,這個是JPA的配置文件哦。文件內容:

    <?xml version="1.0"?>

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"

     version="1.0">

    <persistence-unit name="jpa" transaction-type="RESOURCE_LOCAL">

    <class>cn.itcast.cc.jpa.entity.Customer</class>

    <!-- JPA實現,使用hibernate -->

    <properties>

    <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>

    <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa"/>

    <property name="hibernate.connection.username" value="root"/>

    <property name="hibernate.connection.password" value="root"/>

    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>

    <property name="hibernate.hbm2ddl.auto" value="create"/>

    <property name="hibernate.show_sql" value="true"/>

    </properties>

    </persistence-unit>

    </persistence>

    5.創建“cn.itcast.cc.jpa.entity.Customer”實體類:

    package cn.itcast.cc.jpa.entity;

    import javax.persistence.Entity;

    import javax.persistence.GeneratedValue;

    import javax.persistence.Id;

    @Entity // 必須指定

    public class Customer {

    @Id // 必須指定

    @GeneratedValue

    private Integer id;

    private String name;

    // getters And setters...

    }

    其中“@Entity”與“@Id”必須指定,JPA通過這些注解生成相應的表和字段。加在屬性上的注解也可以加在屬性的gettersetter方法。這些用于設置字段的注解,要么全加在屬性上,要么全加在屬性方法上。JPA以“@Id”所在位置為參照,判斷應該使用屬性上的注解還是屬性方法上的注解。

    6.編寫測試類:

    package cn.itcast.cc.jpa;

    import javax.persistence.EntityManager;

    import javax.persistence.EntityManagerFactory;

    import javax.persistence.EntityTransaction;

    import javax.persistence.Persistence;

    import cn.itcast.cc.jpa.entity.Customer;

    public class App {

    public static void main(String[] args){

    // 創建實體管理對象工廠,相當于HiberanteSessionFactory

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa");

    // 創建實體管理對象,相當于HiberanteSession

    EntityManager em = emf.createEntityManager();

    // 獲取實體事務對象

    EntityTransaction et = em.getTransaction();

    // 開始事務

    et.begin();

    // 創建Customer實體對象

    Customer customer = new Customer();

    customer.setName("changcheng");

    // 持久化customer實體對象(保存)

    em.persist(customer);

    // 提交事務

    et.commit();

    // 關閉

    em.close();

    emf.close();

    }

    }

    Very簡單吧!強悍的地方是我們可以將hibernate更換為其他實現了JPA接口的框架,然后修改一個persistence.xml文件的配置信息,其他地方無需修改。

    二、JPACURD

    JPACURDHibernateCURD操作不大相似,但也十分簡單。

    1.插入記錄

    上邊的例子,我們正是使用到插入的方法,將實體保存到數據庫:

    @Test

    public void create(){

    EntityManager em = emf.createEntityManager();

    EntityTransaction et = em.getTransaction();

    et.begin();

    Customer customer = new Customer();

    customer.setName("china");

    // 保存到數據庫

    em.persist(customer);

    et.commit();

    em.close();

    emf.close();

    }

    2.更新記錄

    JPA中沒有update方法,我們需要先取出記錄。然后再對記錄進行修改,持久化對象可以自動更新到數據庫中。

    @Test

    public void update(){

    EntityManager em = emf.createEntityManager();

    EntityTransaction et = em.getTransaction();

    et.begin();

         // 查詢數據

    Customer customer = em.find(Customer.class, new Integer(1));

    // 更新數據

    customer.setName("new name");

    et.commit();

    em.close();

    emf.close();

    }

    還可以使用“customer = em.getReference(Customer.class, new Integer(1));”。find方法相當于Hibernateget方法,getReference相當于Hibernateload方法。

    3.查詢記錄

    查詢可以使用findgetReference方法,這里不列出了。

    4.刪除記錄

    JPA有一個remove方法,用來刪除查詢到的實體。

    @Test

    public void remove(){

    EntityManager em = emf.createEntityManager();

    EntityTransaction et = em.getTransaction();

    et.begin();

    // 查詢數據

    Customer customer = em.getReference(Customer.class, new Integer(1));

    // 刪除數據

    em.remove(customer);

    et.commit();

    em.close();

    emf.close();

    }

    JPA還有一個Merge的方法,用于同步游離狀態。“cus = em.merge(customer); merge返回的cus為緩存中持久化對象的引用,customer則不是。

    三、JPA中的注解

    我們在學習hibernate時使用entity.hbm.xml映射文件,描述對象與對象的關系,對象與數據表格的配置。那是一件十分郁悶的工作,JPA中支持使用注解描述以上關系,Hibernate也支持。使用注解描述,更直觀、簡單。

    1.Table

    Table用來定義entity主表的namecatalogschema等屬性。

    元數據屬性說明:

    · name: 表名

    · catalog: 對應關系數據庫中的catalog

    · schema:對應關系數據庫中的schema

    · UniqueConstraints:定義一個UniqueConstraint數組,指定需要建唯一約束的列

    2.SecondaryTable

    一個entity class可以映射到多表,SecondaryTable用來定義單個從表的名字,主鍵名字等屬性。使用SecondaryTable可以實現一對一關系的主鍵關聯。

    元數據屬性說明:

    · name: 表名

    · catalog: 對應關系數據庫中的catalog

    · schema:對應關系數據庫中的schema

    · pkJoin: 定義一個PrimaryKeyJoinColumn數組,指定從表的主鍵列

    · UniqueConstraints:定義一個UniqueConstraint數組,指定需要建唯一約束的列

    下面的代碼說明Customer類映射到兩個表,主表名是CUSTOMER,從表名是CUST_DETAIL,從表的主鍵列和主表的主鍵列類型相同,列名為CUST_ID

    @Entity

    @Table(name="CUST")

    public class Customer { ... }

    3.SecondaryTables

    當一個entity class映射到一個主表和多個從表時,用SecondaryTables來定義各個從表的屬性。

    元數據屬性說明:

    · value: 定義一個SecondaryTable數組,指定每個從表的屬性。

    @Entity

    @Table(name="CUSTOMER")

    @SecondaryTable(name="CUST_DETAIL",pkJoin=@PrimaryKeyJoinColumn(name="CUST_ID"))

    public class Customer { ... }

    4.UniqueConstraint

    UniqueConstraint定義在TableSecondaryTable元數據里,用來指定建表時需要建唯一約束的列。

    元數據屬性說明:

    · columnNames:定義一個字符串數組,指定要建唯一約束的列名。

    @Table(name = "CUSTOMER")

    @SecondaryTables(value = {

    @SecondaryTable(name = "CUST_NAME", pkJoin = { @PrimaryKeyJoinColumn(name = "STMO_ID", referencedColumnName = "id") }),

    @SecondaryTable(name = "CUST_ADDRESS", pkJoin = { @PrimaryKeyJoinColumn(name = "STMO_ID", referencedColumnName = "id") }) })

    public class Customer {}

    5.Column

    Column元數據定義了映射到數據庫的列的所有屬性:列名,是否唯一,是否允許為空,是否允許更新等。

    元數據屬性說明:

    · name:列名。

    · unique: 是否唯一

    · nullable: 是否允許為空

    · insertable: 是否允許插入

    · updatable: 是否允許更新

    · columnDefinition: 定義建表時創建此列的DDL

    · secondaryTable: 從表名。如果此列不建在主表上(默認建在主表),該屬性定義該列所在從表的名字。

    @Entity

    @Table(name="EMPLOYEE", uniqueConstraints={@UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})})

    public class Employee { ... }

    6.JoinColumn

    如果在entity classfield上定義了關系(one2oneone2many等),我們通過JoinColumn來定義關系的屬性。JoinColumn的大部分屬性和Column類似。

    元數據屬性說明:

    · name:列名。

    · referencedColumnName:該列指向列的列名(建表時該列作為外鍵列指向關系另一端的指定列)

    · unique: 是否唯一

    · nullable: 是否允許為空

    · insertable: 是否允許插入

    · updatable: 是否允許更新

    · columnDefinition: 定義建表時創建此列的DDL

    · secondaryTable: 從表名。如果此列不建在主表上(默認建在主表),該屬性定義該列所在從表的名字。

    下面的代碼說明CustomOrder是一對一關系。在Order對應的映射表建一個名為CUST_ID的列,該列作為外鍵指向Custom對應表中名為ID的列。

    public class Person {

    @Column(name = "PERSONNAME", unique = true, nullable = false, updatable = true)

    private String name;

    @Column(name = "PHOTO", columnDefinition = "BLOB NOT NULL", secondaryTable = "PER_PHOTO")

    private byte[] picture;

    }

    7.JoinColumns

    如果在entity classfield上定義了關系(one2oneone2many等),并且關系存在多個JoinColumn,用JoinColumns定義多個JoinColumn的屬性。

    元數據屬性說明:

    · value: 定義JoinColumn數組,指定每個JoinColumn的屬性。

    下面的代碼說明CustomOrder是一對一關系。在Order對應的映射表建兩列,一列名為CUST_ID,該列作為外鍵指向Custom對應表中名為ID的列,另一列名為CUST_NAME,該列作為外鍵指向Custom對應表中名為NAME的列。

    public class Custom {

    @OneToOne

    @JoinColumn(name = "CUST_ID", referencedColumnName = "ID", unique = true, nullable = true, updatable = true)

    public Order getOrder() {

    return order;

    }

    }

    8.Id

    聲明當前field為映射表中的主鍵列。id值的獲取方式有五種:TABLE, SEQUENCE, IDENTITY, AUTO, NONEOracleDB2支持SEQUENCESQL ServerSybase支持IDENTITY,mysql支持AUTO。所有的數據庫都可以指定為AUTO,我們會根據不同數據庫做轉換。NONE (默認)需要用戶自己指定Id的值。元數據屬性說明:

    · generate():主鍵值的獲取類型

    · generator():TableGenerator的名字(當generate=GeneratorType.TABLE才需要指定該屬性)

    下面的代碼聲明Task的主鍵列id是自動增長的。(OracleDB2從默認的SEQUENCE取值,SQL ServerSybase該列建成IDENTITYmysql該列建成auto increment)

    public class Custom {

    @OneToOne

    @JoinColumns( { @JoinColumn(name = "CUST_ID", referencedColumnName = "ID"),

    @JoinColumn(name = "CUST_NAME", referencedColumnName = "NAME") })

    public Order getOrder() {

    return order;

    }

    }

    9.IdClass

    entity class使用復合主鍵時,需要定義一個類作為id classid class必須符合以下要求:類必須聲明為public,并提供一個聲明為public的空構造函數。必須實現Serializable接,覆寫 equals()hashCode()方法。entity class的所有id fieldid class都要定義,且類型一樣。

    元數據屬性說明:

    · value: id class的類名

    @Entity

    @Table(name = "OTASK")

    public class Task {

    @Id(generate = GeneratorType.AUTO)

    public Integer getId() {

    return id;

    }

    }

    public class EmployeePK implements java.io.Serializable {

    String empName;

    Integer empAge;

    public EmployeePK() {......}

    public boolean equals(Object obj){......}

    public int hashCode(){......}

    }

    @IdClass(value = com.acme.EmployeePK.class)

    @Entity(access = FIELD)

    public class Employee {

    @Id

    String empName;

    @Id

    Integer empAge;

    }

    10.MapKey

    在一對多,多對多關系中,我們可以用Map來保存集合對象。默認用主鍵值做key,如果使用復合主鍵,則用id class的實例做key,如果指定了name屬性,就用指定的field的值做key

    元數據屬性說明:

    · name: 用來做keyfield名字

    下面的代碼說明PersonBook之間是一對多關系。Personbooks字段是Map類型,用Bookisbn字段的值作為Mapkey

    11.OrderBy

    在一對多,多對多關系中,有時我們希望從數據庫加載出來的集合對象是按一定方式排序的,這可以通過OrderBy來實現,默認是按對象的主鍵升序排列。

    元數據屬性說明:

    · value: 字符串類型,指定排序方式。格式為"fieldName1 [ASC|DESC],fieldName2 [ASC|DESC],......",排序類型可以不指定,默認是ASC

    下面的代碼說明PersonBook之間是一對多關系。集合books按照Bookisbn升序,name降序排列。

    12.PrimaryKeyJoinColumn

    在三種情況下會用到PrimaryKeyJoinColumn

    · 繼承。

    · entity class映射到一個或多個從表。從表根據主表的主鍵列(列名為referencedColumnName值的列),建立一個類型一樣的主鍵列,列名由name屬性定義。

    · one2one關系,關系維護端的主鍵作為外鍵指向關系被維護端的主鍵,不再新建一個外鍵列。

    元數據屬性說明:

    · name:列名。

    · referencedColumnName:該列引用列的列名

    · columnDefinition: 定義建表時創建此列的DDL

    下面的代碼說明Customer映射到兩個表,主表CUSTOMER,從表CUST_DETAIL,從表需要建立主鍵列CUST_ID,該列和主表的主鍵列id除了列名不同,其他定義一樣。

    @Table(name = "PERSON")

    public class Person {

    @OneToMany(targetEntity = Book.class, cascade = CascadeType.ALL, mappedBy = "person")

    @MapKey(name = "isbn")

    private Map books = new HashMap();

    }

    @Table(name = "MAPKEY_PERSON")

    public class Person {

    @OneToMany(targetEntity = Book.class, cascade = CascadeType.ALL, mappedBy = "person")

    @OrderBy(name = "isbn ASC, name DESC")

    private List books = new ArrayList();

    }

    下面的代碼說明EmployeeEmployeeInfo是一對一關系,Employee的主鍵列id作為外鍵指向EmployeeInfo的主鍵列INFO_ID

    13.PrimaryKeyJoinColumns

    如果entity class使用了復合主鍵,指定單個PrimaryKeyJoinColumn不能滿足要求時,可以用PrimaryKeyJoinColumns來定義多個PrimaryKeyJoinColumn

    元數據屬性說明:

    · value: 一個PrimaryKeyJoinColumn數組,包含所有PrimaryKeyJoinColumn

    下面的代碼說明了EmployeeEmployeeInfo是一對一關系。他們都使用復合主鍵,建表時需要在Employee表建立一個外鍵,從Employee的主鍵列id,name指向EmployeeInfo的主鍵列INFO_IDINFO_NAME

    @Entity

    @Table(name="CUSTOMER")

    @SecondaryTable(name="CUST_DETAIL",pkJoin=@PrimaryKeyJoinColumn(name="CUST_ID"referencedColumnName="id"))

    public class Customer {

    @Id(generate = GeneratorType.AUTO)

    public Integer getId() {

    return id;

    }

    }

    @Table(name = "Employee")

    public class Employee {

    @OneToOne

    @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "INFO_ID")

    EmployeeInfo info;

    }

    @Entity

    @IdClass(EmpPK.class)

    @Table(name = "EMPLOYEE")

    public class Employee {

    private int id;

    private String name;

    private String address;

    @OneToOne(cascade = CascadeType.ALL)

    @PrimaryKeyJoinColumns( {

    @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "INFO_ID"),

    @PrimaryKeyJoinColumn(name = "name", referencedColumnName = "INFO_NAME") })

    EmployeeInfo info;

    }

    @Entity

    @IdClass(EmpPK.class)

    @Table(name = "EMPLOYEE_INFO")

    public class EmployeeInfo {

    @Id

    @Column(name = "INFO_ID")

    private int id;

    @Id

    @Column(name = "INFO_NAME")

    private String name;

    }

    14.Transient

    Transient用來注釋entity的屬性,指定的這些屬性不會被持久化,也不會為這些屬性建表。

    15.Version

    Version指定實體類在樂觀事務中的version屬性。在實體類重新由EntityManager管理并且加入到樂觀事務中時,保證完整性。每一個類只能有一個屬性被指定為versionversion屬性應該映射到實體類的主表上。

    下面的代碼說明versionNum屬性作為這個類的version,映射到數據庫中主表的列名是OPTLOCK

    16.Lob

    Lob指定一個屬性作為數據庫支持的大對象類型在數據庫中存儲。使用LobType這個枚舉來定義Lob是二進制類型還是字符類型。

    LobType枚舉類型說明:

    · BLOB 二進制大對象,Byte[]或者Serializable的類型可以指定為BLOB

    · CLOB 字符型大對象,char[]Character[]String類型可以指定為CLOB

    元數據屬性說明:

    · fetch: 定義這個字段是lazy loaded還是eagerly fetched。數據類型是FetchType枚舉,默認為LAZY,lazy loaded.

    · type: 定義這個字段在數據庫中的JDBC數據類型。數據類型是LobType枚舉,默認為BLOB

    下面的代碼定義了一個BLOB類型的屬性和一個CLOB類型的屬性。

    17.JoinTable

    JoinTablemany-to-many關系的所有者一邊定義。如果沒有定義JoinTable,使用JoinTable的默認值。

    元數據屬性說明:

    · table:這個join tableTable定義。

    · joinColumns:定義指向所有者主表的外鍵列,數據類型是JoinColumn數組。

    · inverseJoinColumns:定義指向非所有者主表的外鍵列,數據類型是JoinColumn數組。

    下面的代碼定義了一個連接表CUSTPHONEjoin tablejoin table的表名是CUST_PHONE,包含兩個外鍵,一個外鍵是CUST_ID,指向表CUST的主鍵ID,另一個外鍵是PHONE_ID,指向表PHONE的主鍵ID

    18.TableGenerator

    TableGenerator定義一個主鍵值生成器,在Id這個元數據的generateTABLE時,generator屬性中可以使用生成器的名字。生成器可以在類、方法或者屬性上定義。

    生成器是為多個實體類提供連續的ID值的表,每一行為一個類提供ID值,ID值通常是整數。

    元數據屬性說明:

    · name:生成器的唯一名字,可以被Id元數據使用。

    · table:生成器用來存儲id值的Table定義。

    · pkColumnName:生成器表的主鍵名稱。

    · valueColumnName:生成器表的ID值的列名稱。

    · pkColumnValue:生成器表中的一行數據的主鍵值。

    · initialValue:id值的初始值。

    · allocationSize:id值的增量。

    下面的代碼定義了兩個生成器empGenaddressGen,生成器的表是ID_GEN

    @Transient

    private String name;

    @Version

    @Column("OPTLOCK")

    protected int getVersionNum() { return versionNum; }

    @Lob

    @Column(name="PHOTO" columnDefinition="BLOB NOT NULL")

    protected JPEGImage picture;

    @Lob(fetch=EAGER, type=CLOB)

    @Column(name="REPORT")

    protected String report;

    19.SequenceGenerator

    SequenceGenerator定義一個主鍵值生成器,在Id這個元數據的generator屬性中可以使用生成器的名字。生成器可以在類、方法或者屬性上定義。生成器是數據庫支持的sequence對象。

    元數據屬性說明:

    · name:生成器的唯一名字,可以被Id元數據使用。

    · sequenceName:數據庫中,sequence對象的名稱。如果不指定,會使用提供商指定的默認名稱。

    · initialValue:id值的初始值。

    · allocationSize:id值的增量。

    下面的代碼定義了一個使用提供商默認名稱的sequence生成器。

    20.DiscriminatorColumn

    DiscriminatorColumn定義在使用SINGLE_TABLEJOINED繼承策略的表中區別不繼承層次的列。

    元數據屬性說明:

    · name:column的名字。默認值為TYPE

    · columnDefinition:生成DDLsql片斷。

    · length:String類型的column的長度,其他類型使用默認值10

    下面的代碼定義了一個列名為DISC,長度為20String類型的區別列。

    @JoinTable(table = @Table(name = CUST_PHONE), joinColumns = @JoinColumn(name = "CUST_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "PHONE_ID", referencedColumnName = "ID"))

    @Entity

    public class Employee {

    // ...

    @TableGenerator(name = "empGen", table = @Table(name = "ID_GEN"), pkColumnName = "GEN_KEY", valueColumnName = "GEN_VALUE", pkColumnValue = "EMP_ID", allocationSize = 1)

    @Id(generate = TABLE, generator = "empGen")

    public int id;

    // ...

    }

    @Entity

    public class Address {

    // ...

    @TableGenerator(name = "addressGen", table = @Table(name = "ID_GEN"), pkColumnValue = "ADDR_ID")

    @Id(generate = TABLE, generator = "addressGen")

    public int id;

    // ...

    }

    這部分資料并非本人一一總結,而是取自互聯網。

    其中有一部分的內容,在明天的課程中才會講到。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 好猛好深好爽好硬免费视频| 亚洲v高清理论电影| 国产网站免费观看| 成年女人毛片免费观看97| 亚洲免费福利在线视频| 国产电影午夜成年免费视频| 97在线视频免费| 57pao国产成视频免费播放 | 亚洲AV无码一区二区二三区入口| 亚洲情XO亚洲色XO无码| 亚洲av激情无码专区在线播放| 亚洲AV无码专区国产乱码4SE| 久久精品国产96精品亚洲 | 免费观看的毛片手机视频| 永久黄网站色视频免费观看| 国产成人免费a在线视频色戒| 伊人久久亚洲综合影院| 国产精品亚洲二区在线观看| 亚洲综合另类小说色区| 久久亚洲一区二区| 亚洲女人初试黑人巨高清| 在线观看日本亚洲一区| 理论亚洲区美一区二区三区 | 亚洲一区二区三区精品视频| 国产 亚洲 中文在线 字幕| 久久人午夜亚洲精品无码区| 欧洲美女大片免费播放器视频| 香蕉视频在线免费看| 日本在线看片免费人成视频1000 | 一级大黄美女免费播放| a毛片视频免费观看影院| 最近免费中文字幕高清大全| 免费电影在线观看网站| 亚洲AⅤ视频一区二区三区| 国产亚洲综合网曝门系列| 亚洲理论精品午夜电影| 国产在亚洲线视频观看| 本免费AV无码专区一区| 91精品免费国产高清在线| 国产一区视频在线免费观看| 九月丁香婷婷亚洲综合色|