一個實體簡單的說就是在資料庫中擁有一個表格,並擁有自已的資料庫識別(Database identity)。
一個簡單的實體與實體間之關係為多對一的關係,例如在學校宿舍中,使用者與房間的關係就是多對一的關係,多個使用者可以居住於一個房間。
如上圖所示的,可以藉由room_id讓使用者與房間產生關聯,您可以如下建立user與room表格:
用程式來表示的話,首先看看User類別:
package onlyfun.caterpillar;
public class User ... {
private Integer id;
private String name;
private Room room;
public User() ...{
}
public Integer getId() ...{
return id;
}
public void setId(Integer id) ...{
this.id = id;
}
public String getName() ...{
return name;
}
public void setName(String name) ...{
this.name = name;
}
public Room getRoom() ...{
return room;
}
public void setRoom(Room room) ...{
this.room = room;
}
}
User類別中有一room屬性,將參考至Room實例,多個User實例可共同參考一個Room實例,Room類別設計如下:
package onlyfun.caterpillar;
public class Room ... {
private Integer id;
private String address;
public Room() ...{
}
public Integer getId() ...{
return id;
}
public void setId(Integer id) ...{
this.id = id;
}
public String getAddress() ...{
return address;
}
public void setAddress(String address) ...{
this.address = address;
}
}
在映射文件方面,先來看看Room.hbm.xml:
<! DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
< hibernate-mapping >
< class name ="onlyfun.caterpillar.Room" table ="room" >
< id name ="id" column ="id" >
< generator class ="native" />
</ id >
< property name ="address"
column ="address"
type ="java.lang.String" />
</ class >
</ hibernate-mapping >
沒什麼,很簡單的一個映射文件,而在User.hbm.xml中,使用<many-to-one>標籤來映射多對一關係:
<? xml version="1.0" encoding="utf-8" ?>
<! DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
< hibernate-mapping >
< class name ="onlyfun.caterpillar.User" table ="user" >
< id name ="id" column ="id" type ="java.lang.Integer" >
< generator class ="native" />
</ id >
< property name ="name" column ="name" type ="java.lang.String" />
< many-to-one name ="room"
column ="room_id"
class ="onlyfun.caterpillar.Room"
cascade ="all"
outer-join ="true" />
</ class >
</ hibernate-mapping >
在<many-to-one>的設定中,cascade表示主控方(User)進行save-update、delete等相關操作時,被控方(Room)是否也一併進行相關操作,簡單的說,也就是您儲存或更新User實例時,當中的Room實例是否一併對資料庫發生儲存或操作,設定為 all,表示主控方任何操作,被控方也進行對應操作。
一個儲存的例子如下:
room1.setAddress( " NTU-M8-419 " );
Room room2 = new Room();
room2.setAddress( " NTU-G3-302 " );
User user1 = new User();
user1.setName( " bush " );
user1.setRoom(room1);
User user2 = new User();
user2.setName( " caterpillar " );
user2.setRoom(room1);
User user3 = new User();
user3.setName( " momor " );
user3.setRoom(room2);
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(user1); // 主控方操作,被控方也會對應操作
session.save(user2);
session.save(user3);
tx.commit();
session.close();
資料庫中將儲存以下的內容:
+ -- -----+-------------+-----------+
| id | name | room_id |
+ -- -----+-------------+-----------+
| 1 | bush | 1 |
| 2 | caterpillar | 1 |
| 3 | momor | 2 |
+ -- -----+-------------+-----------+
3 rows in set ( 0.00 sec)
mysql > select * from room;
+ -- --+-------------------+
| id | address |
+ -- --+-------------------+
| 1 | NTU - M8 - 419 |
| 2 | NTU - G3 - 302 |
+ -- --+-------------------+
2 rows in set ( 0.00 sec)
在查詢時的例子如下:
Session session = sessionFactory.openSession();
User user = (User) session.load(User.class, new Integer(1));
System.out.println(user.getName());
System.out.println(user.getRoom().getAddress());
session.close();
Hibernate:
select user0_.id as id1_, user0_.name as name0_1_, user0_.room_id as room3_0_1_,
room1_.id as id0_, room1_.address as address1_0_ from user user0_
left outer join room room1_ on user0_.room_id = room1_.id where user0_.id = ?
在不設定outer - join為true的情況下,Hibernate則使用以下的SQL分別查詢user與room表格:
Hibernate:
select user0_.id as id0_, user0_.name as name0_0_, user0_.room_id as room3_0_0_
from user user0_ where user0_.id = ?
Hibernate:
select room0_.id as id0_, room0_.address as address1_0_
from room room0_ where room0_.id = ?