亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java的Hibernate框架中的雙向主鍵關聯(lián)與雙向外鍵關聯(lián)

 更新時間:2016年06月18日 18:29:19   作者:zhang_xinxiu  
Hibernate想要實現(xiàn)雙向的關聯(lián)就必須在映射文件的兩端同時配置<one-to-one>,另外還要在主映射的一端采用foreign外鍵關聯(lián)屬性,下面我們就一起來看一下Java的Hibernate框架中的雙向主鍵關聯(lián)與雙向外鍵關聯(lián)方法:

一、雙向主鍵關聯(lián)
雙向的主鍵關聯(lián)其實是單向一對一主鍵關聯(lián)的一種特殊情況,只不過要在關聯(lián)對象的兩端的映射文件中都要進行<one-to-one>的配置,另外還要在主映射的主鍵一端采用foreign外鍵關聯(lián)屬性。
這里同樣使用Person和IdCard來討論,一個人對應著一個唯一的身份證,而且一個身份證也唯一映射著一個人,所以這就產(chǎn)生了雙向的關聯(lián)關系,Person的主鍵同樣也是IdCard的主鍵,分別是主鍵的同時也是外鍵,這種關聯(lián)關系成為雙向一對一映射,表現(xiàn)到關系模型中可如下圖:

2016618181616061.png (592×196)

圖中的兩個表采用了主鍵關聯(lián),person的主鍵是idCard的主鍵,所以它們之間構成了朱外鍵的約束關系,并且保證唯一性,映射到對象模型中,轉(zhuǎn)變?yōu)閜erson類和idCard類的一對一關系,如下圖:

2016618181641381.png (414×131)

這種一對一的關系上篇文章中也有講到用的是<one-to-one>標簽,另外這種一對一映射又是雙向的,所以要在兩個對象之間同時配置<one-to-one>,首先來看idCard對應的類代碼和映射文件代碼。

1、IdCard對應的信息
IdCard.java類,IdCard類和Person類之間有一對一的關聯(lián)關系所以要在IdCard類中添加對應的Person屬性,這是為了能在映射文件中的外鍵中添加對應的屬性,設置對應的外鍵關聯(lián)類。

package com.src.hibernate; 
 
public class IdCard { 
   
  //id屬性 
  private int id; 
  public int getId() { 
    return id; 
  } 
  public void setId(int id) { 
    this.id = id; 
  } 
   
  //卡號屬性 
  private String cardNo; 
  public String getCardNo() { 
    return cardNo; 
  } 
  public void setCardNo(String cardNo) { 
    this.cardNo = cardNo; 
  } 
   
  //卡號對應的人 
  private Person person; 
  public Person getPerson(){ 
    return person; 
  } 
  public void setPerson(Person person){ 
    this.person=person; 
  } 
} 

IdCard.hbm.xml映射文件,在映射文件中添加外鍵屬性person,并添加對應的<one-to-one>標簽,目的是強制約束person類來實現(xiàn)一對一的映射關系,最后在映射中將constrained屬性設為true,保證強制約束關系。

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- Generated 2014-5-15 23:47:00 by Hibernate Tools 3.4.0.CR1 --> 
<hibernate-mapping> 
  <class name="com.src.hibernate.IdCard" table="IDCARD"> 
    <id name="id" type="int" column="personId"> 
      <generator class="foreign"> 
        <param name="property">person</param> 
      </generator> 
    </id> 
     
    <property name="cardNo" type="string" column="cardno"></property> 
    <one-to-one name="person" constrained="true"></one-to-one> 
  </class> 
</hibernate-mapping> 

2、Person對應的信息
Person.java類,在該類中除了添加基本的屬性外還要添加對應的IdCard類作為屬性,因為它們之間是一對一的雙向關聯(lián)關系,所以在Person類中同樣要添加IdCard類,相同的道理IdCard類中同樣添加了Person類屬性。

package com.src.hibernate; 
 
public class Person { 
   
  //id號 
  private int id; 
  public int getId() { 
    return id; 
  } 
  public void setId(int id) { 
    this.id = id; 
  } 
   
  //姓名 
  private String name; 
  public String getName() { 
    return name; 
  } 
  public void setName(String name) { 
    this.name = name; 
  } 
   
  //idCard 
  private IdCard idcard; 
  public IdCard getIdcard() { 
    return idcard; 
  } 
  public void setIdcard(IdCard idcard) { 
    this.idcard = idcard; 
  } 
} 

Person.hbm.xml映射文件,該文件中主鍵生成策略沒有特殊的要求,因為它和IdCard類相互制約的關系,它的主鍵和外鍵都是IdCard的主鍵,另外因為是一對一關系所以要在映射文件中添加<one-to-one>標簽來標示。

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- Generated 2014-5-15 23:47:00 by Hibernate Tools 3.4.0.CR1 --> 
<hibernate-mapping> 
  <class name="com.src.hibernate.Person" table="PERSON"> 
    <id name="id" type="int" column="personId"> 
      <generator class="native"></generator> 
    </id> 
     
    <property name="name" type="string" column="personName"></property> 
  <!-- 
  one-to-one標簽指示Hibernate如何加載其關聯(lián)對象,默認根據(jù)主鍵加載,也就是拿到關系字段值,根據(jù)對端的主鍵來加載關聯(lián)對象 
   --> 
  <one-to-one name="idcard"></one-to-one> 
  </class> 
</hibernate-mapping> 

3、Hibernate映射文件
上面的類和映射文件配置好后接下來要在Hibernate.cfg.xml中配置與數(shù)據(jù)庫映射的信息,需要將兩個配置文件添加到Hibernate配置文件中,這樣在生成對應的數(shù)據(jù)庫時才能找到對應的生成項。

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC 
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
  <session-factory> 
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_one2one_pk1</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.connection.password">1234</property> 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
     
    <mapping resource="com/src/hibernate/Person.hbm.xml"/> 
    <mapping resource="com/src/hibernate/IdCard.hbm.xml" ></mapping> 
  </session-factory> 
</hibernate-configuration> 

 4、生成結果
配置完成后就可以將上面的內(nèi)容生成對應的數(shù)據(jù)庫了,在數(shù)據(jù)庫中它會按照配置的內(nèi)容生成相應的表結構,在表中有相應的外鍵和主鍵字段。生成表結構時Hibernate會在控制臺輸出相應的SQL語句,如下:

alter table IDCARD drop foreign key FK806F76ABAC038CD8 
drop table if exists IDCARD 
drop table if exists PERSON 
create table IDCARD (personId integer not null, cardno varchar(255), primary key (personId)) 
create table PERSON (personId integer not null auto_increment, personName varchar(255), primary key (personId)) 
alter table IDCARD add index FK806F76ABAC038CD8 (personId), add constraint FK806F76ABAC038CD8 foreign key (personId) references PERSON (personId) 

生成的表結構如下圖:

2016618182053824.png (677×394)

在兩張表中同時生成了personId主鍵,并且也是相應的外鍵,它同時限制約束了兩張表的主鍵相同且唯一。

5、寫入加載測試
生成表后測試下對表的寫入和從表中讀取數(shù)據(jù),編寫相應的測試類,測試采用的是單元測試,編寫對應的測試方法。
5.1 寫入測試
在寫入到數(shù)據(jù)庫時一定要注意寫入的兩個對象都要轉(zhuǎn)化到對應的Trainent狀態(tài),否則會出現(xiàn)狀態(tài)轉(zhuǎn)化的錯誤,測試代碼如下:

public void testSave1(){ 
  Session session=null; 
  try{ 
    //創(chuàng)建一個會話對象 
    session=HibernateUtils.getSession(); 
    //開啟會話事務 
    session.beginTransaction(); 
     
    //創(chuàng)建person對象,并保存 
    Person person=new Person(); 
    person.setName("zhangsan"); 
    session.save(person); 
     
    //創(chuàng)建idCard對象,并保存 
    IdCard idcard=new IdCard(); 
    idcard.setCardNo("1111111111111"); 
    idcard.setPerson(person); 
    session.save(idcard); 
     
    //提交事務,修改數(shù)據(jù)庫 
    session.getTransaction().commit(); 
     
  }catch(Exception e){ 
    //打印錯誤信息 
    e.printStackTrace(); 
    //業(yè)務回滾 
    session.getTransaction().rollback(); 
  }finally{ 
    //關閉會話 
    HibernateUtils.closeSession(session); 
  } 
} 

插入的數(shù)據(jù)如下圖:

2016618182112300.png (677×394)

5.2 加載測試
編寫加載方法,因為關聯(lián)關系是雙向的,所以相應的加載操作應該是通過一端加載另一端,也就是獲取對應的Person類,并通過Person類來獲取對應的IdCard信息,相反的也要成立,代碼如下:

public void testLoad1(){ 
  Session session=null; 
  try{ 
    //創(chuàng)建一個會話對象 
    session=HibernateUtils.getSession(); 
    //開啟會話事務 
    session.beginTransaction(); 
     
    //獲取person對象,并保存 
    Person person=(Person)session.load(Person.class,5); 
    System.out.println("IdCard.Id: "+person.getIdcard().getId()); 
    System.out.println("IdCard.cardno: "+person.getIdcard().getCardNo()); 
     
    //創(chuàng)建idCard對象,并保存 
    IdCard idcard=(IdCard)session.load(IdCard.class, 5); 
    System.out.println("Person.Id: "+idcard.getPerson().getId()); 
    System.out.println("Person.name: "+idcard.getPerson().getName()); 
     
    //提交事務,修改數(shù)據(jù)庫 
    session.getTransaction().commit(); 
     
  }catch(Exception e){ 
    //打印錯誤信息 
    e.printStackTrace(); 
    //業(yè)務回滾 
    session.getTransaction().rollback(); 
  }finally{ 
    //關閉會話 
    HibernateUtils.closeSession(session); 
  } 
} 

運行上面的測試方法,在控制臺打印的相關內(nèi)容如下:

2016618182218465.png (982×182)

二、雙向外鍵關聯(lián)
雙向的外鍵關聯(lián)可以理解為外鍵關聯(lián)的一種特殊情況,這種特殊主要是由于它是一種雙向的對應關系,在前篇文章中提到如果想要在一張表中添加一個外鍵字段的話可以使用<many-to-one>標簽,它會關系模型中生成對應的外鍵列。這里想要實現(xiàn)雙向的外鍵關聯(lián)就必須使用該標簽。
1、對象模型
先來看對象模型,人和身份證屬于一對一的關系,一個人對應著一個身份,所以它們之間的多重性是一對一的,并且這種對應關系是雙向的。所以它的對象模型同雙向主鍵一對一是相同的,如下圖:

2016618182236440.png (414×131)

2、關系模型
對應的關系模型會發(fā)生很大的變化,一對一的外鍵關聯(lián)關系會在一張表中生成對應的外鍵,拿到人和身份證上來說也就是人的關系模型中會有一個身份證號的主鍵列,它們之間形成了雙向的一對一的情況,如下圖:

2016618182252322.png (650×210)

它們之間的對應關系就是上圖中看到的,person表中有idCard表的主鍵,形成了一對一的外鍵關聯(lián)關系,而且是雙向的,也就是說通過person能夠獲取到idCard,另外通過idCard也能獲取到person。
Person對象和IdCard對象內(nèi)的代碼同上篇文章中的對象代碼一致,不在做代碼羅列,唯一不同的是映射文件中的配置問題。
3、映射文件
idCard.hbm.xml映射文件,idCard表不是映射的主表,所以在做一對一的映射時需要使用的是<one-to-one>標簽來配置,并且需要制定person關系模型中的外鍵屬性,具體代碼如下:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- Generated 2014-5-18 22:27:43 by Hibernate Tools 3.4.0.CR1 --> 
<hibernate-mapping> 
  <class name="com.src.hibernate.IdCard" table="IDCARD"> 
    <id name="id" type="int"> 
      <generator class="native" /> 
    </id> 
    <property name="cardNo" type="java.lang.String"> 
      <column name="CARDNO" /> 
    </property> 
     
    <one-to-one name="person" property-ref="idCard"></one-to-one> 
  </class> 
</hibernate-mapping> 

Person.hbm.xml映射文件,person表是映射的主表,需要在該表中添加一個外鍵屬性列來標示idCard表,所以這里需要使用<many-to-one>標簽,在person對象中生成相應的外鍵,并且還要使用unique標明屬性唯一。

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- Generated 2014-5-18 22:27:43 by Hibernate Tools 3.4.0.CR1 --> 
<hibernate-mapping> 
  <class name="com.src.hibernate.Person" table="PERSON"> 
    <id name="id" type="int" column="personId"> 
      <generator class="native" /> 
    </id> 
    <property name="name" type="java.lang.String"> 
      <column name="NAME" /> 
    </property> 
     
    <many-to-one name="idCard" column="idCardNo" unique="true" not-null="true"></many-to-one> 
  </class> 
</hibernate-mapping> 

對象的映射文件配置完成,接下來生成關系模型,SQL語句如下:

alter table PERSON drop foreign key FK8C768F55794A52CA 
drop table if exists IDCARD 
drop table if exists PERSON 
create table IDCARD (id integer not null auto_increment, CARDNO varchar(255), primary key (id)) 
create table PERSON (personId integer not null auto_increment, NAME varchar(255), idCardNo integer not null unique, primary key (personId)) 
alter table PERSON add index FK8C768F55794A52CA (idCardNo), add constraint FK8C768F55794A52CA foreign key (idCardNo) references IDCARD (id) 

生成的SQL語句首先是創(chuàng)建的表,在建表時指定了主鍵列,創(chuàng)建完成后修改了兩個表指定外鍵屬性,形成一對一的關系。

2016618182310444.png (683×291)

編寫測試方法,采用單元測試,加載兩個類的對象,并分別從對象的一端獲取另一個對象

//加載對象,使用IdCard對象裝載person對象 
public void testLoad1(){ 
  Session session=null; 
   
  try{ 
    session=HibernateUtils.getSession(); 
    session.beginTransaction(); 
     
    //獲取IdCard對象,在IdCard中獲取與該對象唯一關聯(lián)的person對象 
    IdCard idcard=(IdCard)session.load(IdCard.class,1); 
    System.out.println("person.Id= "+idcard.getPerson().getId()); 
    System.out.println("idCard.person.name= "+idcard.getPerson().getName()); 
     
    //獲取Person對象,在Person對象中獲取與它唯一關聯(lián)的IdCard對象 
    Person person=(Person)session.load(Person.class,1); 
    System.out.println("idCard.id: "+person.getIdCard().getId()); 
    System.out.println("idCard.cardNo: "+person.getIdCard().getCardNo()); 
     
    //提交事務 
    session.getTransaction().commit(); 
  }catch(Exception e){ 
    e.printStackTrace(); 
    session.getTransaction().rollback(); 
  }finally{ 
    HibernateUtils.closeSession(session); 
  } 
} 

生成的內(nèi)容:

2016618182332548.png (299×94)

對比兩種映射關系,主鍵和外鍵兩種映射,都是雙向的映射關系,需要在對象的兩端同時配置映射關系,不同的是主鍵只需要使用<one-to-one>因為它不需要生成屬性列,但是必須對表的主鍵采用foreign的主鍵生成策略,并標示外鍵對象;外鍵的生成策略則需要采用<many-to-one>標簽來生成新的外鍵列。

結語
雙向關聯(lián)中的一對一映射至此已經(jīng)討論完成,兩篇文章主要討論了雙向關聯(lián)中的兩種用法,其實還是很簡單的,記住一句話想要生成外鍵就使用<many-to-one>標簽,如果唯一那就添加unique屬性,<one-to-one>標簽只是指明了一對一的關系它只是指明一個對象如何加載另一個對象并不在關系模型中添加新列。下篇文章將會對一對多關聯(lián)展開討論。

相關文章

  • Java設計模式之java策略模式詳解

    Java設計模式之java策略模式詳解

    這篇文章主要介紹了Java經(jīng)典設計模式之策略模式,簡單說明了策略模式的概念、原理并結合實例形式分析了java策略模式的具有用法與相關注意事項,需要的朋友可以參考下
    2021-09-09
  • mybatis 為什么千萬不要使用 where 1=1

    mybatis 為什么千萬不要使用 where 1=1

    這篇文章主要介紹了mybatis 為什么千萬不要使用 where 1=1,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • Java 值傳遞和引用傳遞詳解及實例代碼

    Java 值傳遞和引用傳遞詳解及實例代碼

    這篇文章主要介紹了 Java 值傳遞和引用傳遞詳解及實例代碼的相關資料,需要的朋友可以參考下
    2017-03-03
  • SpringBoot如何切換成其它的嵌入式Servlet容器(Jetty和Undertow)

    SpringBoot如何切換成其它的嵌入式Servlet容器(Jetty和Undertow)

    這篇文章主要介紹了SpringBoot如何切換成其它的嵌入式Servlet容器(Jetty和Undertow),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Java?I/O流之打印流詳細使用方法教程

    Java?I/O流之打印流詳細使用方法教程

    java的io是實現(xiàn)輸入和輸出的基礎,可以方便的實現(xiàn)數(shù)據(jù)的輸入和輸出操作,下面這篇文章主要給大家介紹了關于Java?IO流打印流詳細使用的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • Java實戰(zhàn)之用Swing實現(xiàn)通訊錄管理系統(tǒng)

    Java實戰(zhàn)之用Swing實現(xiàn)通訊錄管理系統(tǒng)

    今天給大家?guī)淼氖荍ava實戰(zhàn)的相關知識,文章圍繞著Swing實現(xiàn)通訊錄管理系統(tǒng)展開,文中有非常詳細的代碼示例,需要的朋友可以參考下
    2021-06-06
  • mybatis xml注釋sql的注意事項及說明

    mybatis xml注釋sql的注意事項及說明

    這篇文章主要介紹了mybatis xml注釋sql的注意事項及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java中ExecutorService和ThreadPoolExecutor運行原理

    Java中ExecutorService和ThreadPoolExecutor運行原理

    本文主要介紹了Java中ExecutorService和ThreadPoolExecutor運行原理,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Spring IoC學習之ApplicationContext中refresh過程詳解

    Spring IoC學習之ApplicationContext中refresh過程詳解

    這篇文章主要給大家介紹了關于Spring IoC學習之ApplicationContext中refresh過程的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • 一文詳解如何使用線程池來優(yōu)化我們的應用程序

    一文詳解如何使用線程池來優(yōu)化我們的應用程序

    線程池是一種工具,但并不是適用于所有場景。在使用線程池時,我們需要根據(jù)應用程序的性質(zhì)、計算資源的可用性和應用程序的需求進行適當?shù)呐渲?。本文主要介紹了如何使用線程池來優(yōu)化我們的應用程序,需要的可以參考一下
    2023-04-04

最新評論