多對一關聯映射 many-to-one
關聯映射本質:
* 將關聯關系映射到數據庫,所謂的關聯關系是對象模型在內存中的一個或多個引用。
<many-to-one/>標簽會在多的一端加入一個外鍵,指定一的一端,這個外鍵是由<many-to-one>
中的column屬性定義的,如果忽略了這個屬性那么默認的外鍵與實體的屬性一致
<many-to-one/>標簽的定義示例:
* <many-to-one name="group" column="groupid" cascade="save-update"/>
其中cascade屬性為級聯操作,值可以為all、save-update、delete,默認為none
級聯操作:是對象的連鎖操作
* 級聯操作的解決方法有兩種:1 設cascade屬性,2 先進行save操作
<!--
User: Group:
private int id; private int id;
private String name; private String name;
private Group group;
-->
<class name="com.my.hibernate.Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>

<class name="com.my.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="password"/>
<property name="createTime"/>
<property name="expireTime"/>
<many-to-one name="group" column="groupid" cascade="save-update"/>
</class>

public void testSave1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Group group=new Group();
group.setName("尚學堂");
User user=new User();
user.setName("采10");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
user.setGroup(group);
User user1=new User();
group.setName("尚學堂");
user1.setName("張三");
user1.setPassword("888");
user1.setCreateTime(new Date());
user1.setExpireTime(new Date());
user1.setGroup(group);
//不能成功保存,拋出TransientObjectException異常
//因為Group為Transient狀態,id沒有分配值
//persistent狀態的對象是不能引用trainsient狀態的對象的
session.save(user);
session.save(user1);
session.getTransaction().commit();

}catch(Exception e)
{
e.printStackTrace();
session.getTransaction().rollback();

}finally
{
HibernateUtils.closeSession(session);
}
}

public void testSave2()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Group group=new Group();
group.setName("尚學堂");
session.save(group);
User user=new User();
user.setName("采10");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
user.setGroup(group);
User user1=new User();
group.setName("尚學堂");
user1.setName("張三");
user1.setPassword("888");
user1.setCreateTime(new Date());
user1.setExpireTime(new Date());
user1.setGroup(group);

//可以存儲,因為對Group進行了save操作
session.save(user);
session.save(user1);
session.getTransaction().commit();

}catch(Exception e)
{
e.printStackTrace();
session.getTransaction().rollback();

}finally
{
HibernateUtils.closeSession(session);
}
}

public void testSave3()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Group group=new Group();
group.setName("尚學堂");
User user=new User();
user.setName("采10");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
user.setGroup(group);
User user1=new User();
group.setName("尚學堂");
user1.setName("張三");
user1.setPassword("888");
user1.setCreateTime(new Date());
user1.setExpireTime(new Date());
user1.setGroup(group);
//不會拋出異常,因為采用了cascade屬性,所以它會先保存Group
//采用cascade屬性是解決TransientObjectException異常的一種手段
session.save(user);
session.save(user1);
session.getTransaction().commit();

}catch(Exception e)
{
e.printStackTrace();
session.getTransaction().rollback();

}finally
{
HibernateUtils.closeSession(session);
}
}

public void testload1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
User user=(User)session.load(User.class, 3);
System.out.println(user.getName());
System.out.println(user.getGroup().getName());
session.getTransaction().commit();

}catch(Exception e)
{
e.printStackTrace();
session.getTransaction().rollback();

}finally
{
HibernateUtils.closeSession(session);
}
}
一對一關聯映射 one-to-one
1 主鍵關聯映射(單向關聯Person--->Card)
<one-to-one/>主鍵關聯映射
* 讓兩個實體對象的id保持相同,這樣可以避免多余的字段被創建
* 具體映射:
<id name="id">
person的主鍵來源于Card,也就是共享Card的主鍵
<generator class="foreign">
<param name="property">card</param>
</generator>
</id>
<one-to-one/>標簽的含義,指示hibernate怎么加載它的關聯對象,默認根據主鍵加載,
constrained="true",表明當前主鍵上存在一個約束,person的主鍵作為外鍵參照了Card
<one-to-one name="card" constrained="true"/>

public void testSave1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Card card=new Card();
card.setCardNo("sadfsaffsf");
Person person=new Person();
person.setName("werwer");
person.setCard(card);
//不會出現TransientObjectException異常
//因為一對一主鍵關聯映射中,默認為cascade屬性
session.save(person);
session.getTransaction().commit();

}catch(Exception e)
{
e.printStackTrace();
session.getTransaction().rollback();

}finally
{
HibernateUtils.closeSession(session);
}
}

public void testLoad1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Person person=(Person)session.load(Person.class, 7);
System.out.print(person.getName());
System.out.print(person.getCard().getCardNo());
session.getTransaction().commit();

}catch(Exception e)
{
e.printStackTrace();
session.getTransaction().rollback();

}finally
{
HibernateUtils.closeSession(session);
}
}
一對一關聯映射 one-to-one
2 主鍵關聯映射(雙向關聯Person<--->Card)
需要在Card映射文件中加入<one-to-one/>標簽指向person,指示hibernate如何加載person
默認根據主鍵加載
只能用于查詢,load和get
<!--
Person: Card:
private int id; private int id;
private String name; private String cardNo;
private Card card; private Person person;
-->
<class name="com.my.hibernate.Card" table="t_card">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person"/>
</class>

<class name="com.my.hibernate.Person" table="t_person">
<id name="id">
<generator class="foreign">
<param name="property">card</param>
</generator>
</id>
<property name="name"/>
<one-to-one name="card" constrained="true"/>
</class>
public void testLoad2(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Card card=(Card)session.load(Card.class, 7);
System.out.println(card.getCardNo());
System.out.println(card.getPerson().getName());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
一對一唯一外鍵關聯映射
1 一對一外鍵關聯映射(單向關聯Person--->Card)
<many-to-one/>一對一外鍵關聯映射是多對一的特例,
采用<many-to-one/>標簽,設多的一端的unique="true",這樣就限制了多的一端的多重性為一
<!--
Person: Card:
private int id; private int id;
private String name; private String cardNo;
private Card card; private Person person;
-->
<class name="com.my.hibernate.Person" table="t_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="card" unique="true" column="cardid" cascade="save-update"/>
</class>

<class name="com.my.hibernate.Card" table="t_card">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
一對一唯一外鍵關聯映射
1 一對一外鍵關聯映射(雙向關聯Person<--->Card)
采用<ont-to-one/>標簽,指示hibernate如何加載其關聯對象,默認根據主鍵加載。
外鍵關聯映射中,因為兩個實體采用的是person的外鍵的關系,所以不能指定主鍵相載person,
而要根據person的外鍵加載,所以設property-ref="card"
<!--
Person: Card:
private int id; private int id;
private String name; private String cardNo;
private Card card; private Person person;
-->
<class name="com.my.hibernate.Card" table="t_card">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person" property-ref="card"/>
</class>

<class name="com.my.hibernate.Person" table="t_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="card" unique="true" column="cardid" cascade="save-update"/>
</class>
posted on 2009-11-03 15:53
junly 閱讀(434)
評論(0) 編輯 收藏 所屬分類:
hibernate/orm