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

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

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

    隨筆-126  評論-247  文章-5  trackbacks-0

    一對一關聯有三種情況:
     
    一是關聯的實體都共享同樣的主鍵,二是其中一個實體通過外鍵關聯到另一個實體的主鍵 ,三是通過關聯表來保存兩個實體之間的連接關系。

    接下來要介紹的是,注解形式的一對一單向外鍵關聯的情況。

    環境 :  JDK 1.6,eclipse 3.6,maven 3.0.4,hibernate 3.3.2,junit 4.7,mysql 5.1

     pom.xml 核心部分清單 

    <dependencies>

       <!-- Hibernate framework -->

        <dependency>

          <groupId>org.hibernate</groupId>

          <artifactId>hibernate-core</artifactId>

          <version>3.3.2.GA</version>

        </dependency>

        <!-- Hibernate Dependency Start -->

        <dependency>

          <groupId>cglib</groupId>

          <artifactId>cglib</artifactId>

          <version>2.2</version>

        </dependency>

        <dependency>    

          <groupId>javassist</groupId>    

          <artifactId>javassist</artifactId>    

          <version>3.9.0.GA</version>

        </dependency>

        <dependency>

          <groupId>org.hibernate</groupId>

          <artifactId>hibernate-annotations</artifactId>

          <version>3.4.0.GA</version>

        </dependency>

        <dependency>    

          <groupId>org.slf4j</groupId>    

          <artifactId>slf4j-log4j12</artifactId>    

          <version>1.5.8</version>

        </dependency>

        <!-- Hibernate Dependency End -->

        <!-- mysql driver -->

        <dependency>

          <groupId>mysql</groupId>

          <artifactId>mysql-connector-java</artifactId>

          <version>5.1.17</version>

        </dependency>

        <!-- junit -->

        <dependency>

          <groupId>junit</groupId>

          <artifactId>junit</artifactId>

          <version>4.7</version>

          <scope>test</scope>

        </dependency>

     </dependencies>



    注 : 此處配置 pom.xml 是使用 maven 來管理 jar 包,如果你沒有使用 maven,則需手動導入相關 jar 包。

    ①一對一單向外鍵關聯 :

     實體 bean 

    package net.yeah.fancydeepin.unidirectional.po;

    import java.io.Serializable;

    import javax.persistence.CascadeType;

    import javax.persistence.Column;

    import javax.persistence.Entity;

    import javax.persistence.FetchType;

    import javax.persistence.GeneratedValue;

    import javax.persistence.Id;

    import javax.persistence.OneToOne;

    import org.hibernate.annotations.GenericGenerator;

     

    @Entity

    public class Student implements Serializable{

       private static final long serialVersionUID = 1L;

       private String id;
      
    private String name;
      
    private StudentCard studentCard;

       @Id

       @GenericGenerator(name = "idGenerator", strategy = "uuid")

       @GeneratedValue(generator = "idGenerator")

       @Column(length = 32)

       public String getId() {

          return id;

       }

       @Column(length = 18, nullable = false)

       public String getName() {

          return name;

       }

       @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)

       public StudentCard getStudentCard() {

          return studentCard;

       }

       public void setId(String id) {

          this.id = id;

       }

       public void setName(String name) {

          this.name = name;

       }

       public void setStudentCard(StudentCard studentCard) {

          this.studentCard = studentCard;

       }

    }


    @OneToOne         建立實體 bean 之間的一對一的關聯

    cascade                  級聯策略,即,當對主對象做某種操作時,是否對其相關聯的子對象也做相對應的操作。它有5個值可選,分別是 :

                 CascadeType.PERSIST : 級聯新建

                 CascadeType.REMOVE  :  級聯刪除

                 CascadeType.REFRESH : 級聯刷新

                 CascadeType.MERGE   : 級聯更新

                 CascadeType.ALL     : 囊括以上四項


    fetch                        抓取策略,它有2個值可選,分別是 :

                 FetchType.LAZY   :   延遲抓取

                 FetchType.EAGER  :   立即抓取

    Tips :       延遲抓取數據能夠保證應用只有在需要的時候才去數據庫抓取相應的數據記錄,這樣能夠避免過多,

                 或過早的加載數據庫表中的數據,從而減少應用內存的開銷。

    @JoinColumn     該注解與@Column 注解用法有點相似,可以通過name來指定聯接列的名稱,如果沒有該注解沒有被聲明,

                 默認的聯接列名稱是 : 關聯的類的短類名(首字母小寫,不帶包名)_id。


     實體 bean 
    package net.yeah.fancydeepin.unidirectional.po;

    import java.io.Serializable;

    import java.util.Date;

    import javax.persistence.Column;

    import javax.persistence.Entity;

    import javax.persistence.Id;

    import javax.persistence.Temporal;

    import javax.persistence.TemporalType;

    @Entity

    public class StudentCard implements Serializable{

       private static final long serialVersionUID = 1L;

       private Long id;

       private Date date;

       @Id

       public Long getId() {

          return id;

       }

       @Column(nullable = false)

       @Temporal(TemporalType.DATE)

       public Date getDate() {

          return date;

       }

       public void setId(Long id) {

          this.id = id;

       }

       public void setDate(Date date) {

          this.date = date;

       }

    }

                                     

     hibernate.cfg.xml 清單   

    <hibernate-configuration>

        <session-factory>

            <!-- Database connection settings -->

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

            <property name="connection.url">jdbc:mysql://localhost:3306/temp</property>

            <property name="connection.username">username</property>

            <property name="connection.password">password</property>

            <!-- SQL dialect -->

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


           
    <!-- Enable Hibernate's automatic session context management -->

            <property name="current_session_context_class">thread</property>

            <!-- Echo all executed SQL to stdout -->

            <property name="show_sql">true</property>

            <property name="format_sql">true</property>

            <!-- OneToOne 單向 -->

            <mapping class="net.yeah.fancydeepin.unidirectional.po.Student" />

            <mapping class="net.yeah.fancydeepin.unidirectional.po.StudentCard" />

            <!-- OneToOne 雙向 -->

            <!--

            <mapping class="net.yeah.fancydeepin.bidirectional.po.Student" />

            <mapping class="net.yeah.fancydeepin.bidirectional.po.StudentCard" />

            -->

        </session-factory>

    </hibernate-configuration>




     Junit Test 

    package junit.test;

    import java.util.Date;

    import net.yeah.fancydeepin.unidirectional.po.Student;

    import net.yeah.fancydeepin.unidirectional.po.StudentCard;

    import org.hibernate.Session;

    import org.hibernate.cfg.AnnotationConfiguration;

    import org.hibernate.tool.hbm2ddl.SchemaExport;

    import org.junit.BeforeClass;

    import org.junit.Test;

    public class TestApp {

       private static Session session;

       private static final String ID = "402881f13a5480c2013a5480c3d00001";

       @BeforeClass

       public static void beforeClass(){

          session = new AnnotationConfiguration().configure().buildSessionFactory().getCurrentSession();

       }

       @Test

       public void createTable(){

          new SchemaExport(new AnnotationConfiguration().configure()).create(true, true);

       }

       @Test

       public void insert(){

          Student student = new Student();

          student.setName("fancy");

          StudentCard studentCard = new StudentCard();

          studentCard.setId(3110005981L);

          studentCard.setDate(new Date());

          student.setStudentCard(studentCard);

          session.beginTransaction();

          session.save(student);

          session.getTransaction().commit();

       }

       @Test

       public void query(){

          session.beginTransaction();

          Student student = (Student)session.get(Student.class, ID);

          System.out.println(student.getName());

          //StudentCard studentCard = student.getStudentCard();

     

          //System.out.println(studentCard.getDate());

       }

       @Test

       public void update(){

          session.beginTransaction();

          Student student = (Student)session.get(Student.class, ID);

          student.setName("fancydeepin");

       // StudentCard studentCard = student.getStudentCard();

       // studentCard.setDate(new Date());

       // student.setStudentCard(studentCard);

          session.update(student);

          session.getTransaction().commit();

       }

       @Test

       public void delete(){

          session.beginTransaction();

          Student student = (Student)session.get(Student.class, ID);

       // StudentCard studentCard = student.getStudentCard();

       // session.delete(studentCard);

          session.delete(student);

          session.getTransaction().commit();

       }

    }

    1. 建表

        在 Junit 測試類中執行建表方法 createTable,數據庫中生成表結構 : 

        

        


    2. 插入數據 ( 級聯插入 )

        在 Junit 測試類中執行 insert 方法,后臺發出兩條插入的 SQL 語句,數據庫中產生的數據 :

            

        在這里,student 是主表,studentcard 是從表,Student 類級聯 ( CascadeType.ALL ) 了 StudentCard 類,當 Student 的實例對象被持久化時,

        若 Student 對象的 StudentCard 實例對象不為 null,則該 StudentCard 對象也將被持久化到數據庫,若為 null,則不會被持久化。

    3. 查詢數據 ( 延遲加載 )

        在 Junit 測試類中執行 query 方法,后臺發出 Student 的 select SQL 語句 : 
        
        Hibernate: 
            select
                student0_.id as id0_0_,
                student0_.name as name0_0_,
                student0_.studentCard_id as studentC3_0_0_ 
            from
                Student student0_ 
            where
                student0_.id=?

        若將 query 方法里被注釋的行去掉,后臺除了會發出 Student 的 select SQL 語句之外,還會發出 StudentCard 的 select SQL : 

        Hibernate: 
            select
                student0_.id as id0_0_,
                student0_.name as name0_0_,
                student0_.studentCard_id as studentC3_0_0_ 
            from
                Student student0_ 
            where
                student0_.id=?
        Hibernate: 
            select
                studentcar0_.id as id1_0_,
                studentcar0_.date as date1_0_ 
            from
                StudentCard studentcar0_ 
            where
                studentcar0_.id=?

    4. 更新數據 ( 級聯更新 )
     
        在 Junit 測試類中執行 update 方法,后臺發出 Student 的 update SQL 語句 : 

        Hibernate: 
            update
                Student 
            set
                name=?,
                studentCard_id=? 
            where
                id=?

        若將 update 方法中的注釋行去掉,后臺除了會發出 Student 的 update SQL 語句之外,還會發出 StudentCard 的 update SQL : 

        Hibernate: 
            update
                Student 
            set
                name=?,
                studentCard_id=? 
            where
                id=?
        Hibernate: 
            update
                StudentCard 
            set
                date=? 
            where
                id=?

        注 :  只有當 Student 對象的屬性值發生變化時,才會發出 Student 的 update SQL,如果 Student 對象中的屬性值沒有發生過改變,

                則不會發出 Student 的 update SQL ; StudentCard 也是一樣的。


    5. 刪除數據 ( 級聯刪除 )

        在 Junit 測試類中執行 delete 方法,后臺發出 Student 和 StudentCard 的 delete SQL 語句 : 

        Hibernate: 
            delete 
            from
                Student 
            where
                id=?
        Hibernate: 
            delete 
            from
                StudentCard 
            where
                id=?


        由于是 CascadeType.ALL 的級聯策略,當從表中的記錄被刪除時,主表中被關聯的記錄也將會被刪除掉。

        若是將 delete 方法中的注釋行去掉,將最后注釋行的下一行注釋掉,也就是如果將 session.delete(student); 這行 注釋起來的話,
     
        后臺將拋出   org.hibernate.ObjectDeletedException 的異常,這是由于從表 student 關聯了主表 studentcard,因此不能直接去刪除

        studentcard 表中被 student 表參考的記錄,換句話說就是,在記錄關聯情況下,只有從表中的記錄先被刪除,主表中的記錄才有可能被刪除。


    ②一對一雙向外鍵關聯 : 

        如果,StudentCard 中的 Student 是必須的,也就是說,在 Student 中保存了一個 StudentCard 的引用,在 StudentCard 中也保存了一個 Student 的引用,

        這就成了一對一的雙向關聯,StudentCard 的代碼修改成 :

     實體 bean 
    package net.yeah.fancydeepin.bidirectional.po;

    import java.io.Serializable;

    import java.util.Date;

    import javax.persistence.Column;

    import javax.persistence.Entity;

    import javax.persistence.Id;

    import javax.persistence.OneToOne;

    import javax.persistence.Table;

    import javax.persistence.Temporal;

    import javax.persistence.TemporalType;

    @Entity

    @Table(name = "_studentcard")

    public class StudentCard implements Serializable{

       private static final long serialVersionUID = 1L;

       private Long id;

       private Date date;

       private Student student;

       @Id

       public Long getId() {

          return id;

       }

       @Column(nullable = false)

       @Temporal(TemporalType.DATE)

       public Date getDate() {

          return date;

       }

       @OneToOne(mappedBy = "studentCard")

       public Student getStudent() {

          return student;

       }

       public void setId(Long id) {

          this.id = id;

       }

       public void setDate(Date date) {

          this.date = date;

       }

       public void setStudent(Student student) {

          this.student = student;

       }

    }


        
        mappedBy : 

        相當于 xml 方式配置的 inverse = "true",表示將表間關聯的這種關系的維護交給對方,對方才是關系的真正維護者,擁有主導權。 

        在雙向關聯中,有且僅有一端是作為主體( owner )端存在,主體端負責維護聯接列。對于不需要維護這種關系的從表則通過 mappedBy 屬性進行聲明。

        最后不必也不能再在被關聯端(owned side)定義聯接列了,因為已經在主體端進行了聲明.








      
    posted on 2012-10-13 13:20 fancydeepin 閱讀(7817) 評論(0)  編輯  收藏

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


    網站導航:
     
    主站蜘蛛池模板: 99亚洲乱人伦aⅴ精品| 99久在线国内在线播放免费观看| 亚洲人成网站色在线入口| 丝瓜app免费下载网址进入ios| 亚洲色欲色欲综合网站| 亚洲成a人片毛片在线| 在线观看国产情趣免费视频| 成在线人视频免费视频 | 在线观看亚洲天天一三视| 久久w5ww成w人免费| 国产精品久久亚洲一区二区| 亚洲色欲色欲综合网站| 免费h黄肉动漫在线观看| 亚洲一级毛片免费观看| 一级毛片人与动免费观看| 亚洲国产成人va在线观看网址| 亚洲国产婷婷香蕉久久久久久| 亚欧色视频在线观看免费| 成年网站免费入口在线观看| 亚洲av永久无码精品天堂久久| 亚洲电影日韩精品| 99热在线精品免费全部my| 亚洲毛片无码专区亚洲乱| 亚洲国产精品第一区二区三区| 18勿入网站免费永久| 两个人的视频www免费| 噜噜综合亚洲AV中文无码| 亚洲精品456在线播放| 亚洲三区在线观看无套内射| 日韩一级免费视频| 久久午夜免费视频| 国产一级淫片a免费播放口| 黄色毛片免费观看| 亚洲欧美日韩中文二区| 亚洲福利一区二区精品秒拍| 国产精品亚洲片在线| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 在线观看www日本免费网站| 中文字幕在线免费视频| 色婷婷精品免费视频| 亚洲精华国产精华精华液网站|