Hibernate (八)一對一 (外來鍵關聯方式)
阿新 • • 發佈:2019-01-22
一對一 對映有兩種方式:
主鍵關聯: id 對應 id 兩個主鍵必須相同
外來鍵關聯: id 對應 xxxid 專門設定一個外來鍵屬性 (推薦使用)
外來鍵關聯方式
例如:下面的例子IdCard 表會有一個專門的外來鍵屬性 personId 對應 person 主鍵id
IdCard.java
public class IdCard {
private Integer id;
private String number;
private Person person; // 關聯的公民
IdCard.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.i_hbm_oneToOne">
<class name="IdCard" table="idCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="number"/>
<!-- person屬性,Person型別。
表達的是本類與Person的一對一。
採用基於外來鍵的一對一對映方式,本方有外來鍵方。 -->
<many-to-one name="person" class="Person" column="personId" unique="true"></many-to-one >
</class>
</hibernate-mapping>
Person.java
public class Person {
private Integer id;
private String name;
private IdCard idCard; // 關聯的身份證
Person.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.i_hbm_oneToOne">
<class name="Person" table="person">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<!-- idCard屬性,IdCard型別。
表達的是本類與IdCard的一對一。
採用基於外來鍵的一對一對映方式,本方無外來鍵方。
property-ref屬性:
寫的是對方對映中外來鍵列對應的屬性名。
-->
<one-to-one name="idCard" class="IdCard" property-ref="person"/>
</class>
</hibernate-mapping>
第二種方式:
主鍵關聯
其他一樣只是,對映檔案不同
IdCard.hbm.xml
... ...
<hibernate-mapping package="cn.itcast.i_hbm_oneToOne2">
<class name="IdCard" table="idCard2">
<id name="id">
<!-- 當使用基於主鍵的一對一對映時,
有外來鍵方的主鍵生成策略一定要是foreign。
引數property:
生成主鍵值時所根據的物件。
-->
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<property name="number"/>
<!-- person屬性,Person型別。
表達的是本類與Person的一對一。
採用基於主鍵的一對一對映方式,本方有外來鍵方。 -->
<one-to-one name="person" class="Person" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
Person.hbm.xml
... ...
<hibernate-mapping package="cn.itcast.i_hbm_oneToOne2">
<class name="Person" table="person2">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<!-- idCard屬性,IdCard型別。
表達的是本類與IdCard的一對一。
採用基於主鍵的一對一對映方式,本方無外來鍵方。
-->
<one-to-one name="idCard" class="IdCard"></one-to-one>
</class>
</hibernate-mapping>
測試程式碼
package cn.itcast.i_hbm_oneToOne;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class App {
private static SessionFactory sessionFactory = new Configuration()//
.configure()//
.addClass(Person.class)// 新增Hibernate實體類(載入對應的對映檔案)
.addClass(IdCard.class)// 新增Hibernate實體類(載入對應的對映檔案)
.buildSessionFactory();
// 儲存,有關聯關係
@Test
public void testSave() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 新建物件
Person person = new Person();
person.setName("張三");
IdCard idCard = new IdCard();
idCard.setNumber("100000011X");
// 關聯起來
// person.setIdCard(idCard);
idCard.setPerson(person);
// 儲存
session.save(person);
session.save(idCard);
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 獲取,可以獲取到關聯的對方
@Test
public void testGet() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 獲取一方,並顯示另一方資訊
// Person person = (Person) session.get(Person.class, 1);
// System.out.println(person);
// System.out.println(person.getIdCard());
IdCard idCard = (IdCard) session.get(IdCard.class, 1);
System.out.println(idCard);
System.out.println(idCard.getPerson());
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 解除關聯關係:一對一中,只能有外來鍵方可以維護關聯關係。
@Test
public void testRemoveRelation() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 從有外來鍵方解除關係,可以。
// IdCard idCard = (IdCard) session.get(IdCard.class, 1);
// idCard.setPerson(null);
// 從無外來鍵方解除關係,不可以。
Person person = (Person) session.get(Person.class, 1);
person.setIdCard(null);
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 刪除物件,對關聯物件的影響
@Test
public void testDelete() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// a, 如果沒有關聯的對方:能刪除。
// b, 如果有關聯的對方且可以維護關聯關係(有外來鍵方),他就會先刪除關聯關係,再刪除自己。
// c, 如果有關聯的對方且不能維護關聯關係(無外來鍵方),所以會直接執行刪除自己,就會有異常。
IdCard idCard = (IdCard) session.get(IdCard.class, 1);
session.delete(idCard);
// Person person = (Person) session.get(Person.class, 1);
// session.delete(person);
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
}