现在的位置: 首页 > 综合 > 正文

入門 18 – 多對一實體映射

2013年10月10日 ⁄ 综合 ⁄ 共 3638字 ⁄ 字号 评论关闭
一個實體簡單的說就是在資料庫中擁有一個表格的物件,並擁有自已的資料庫識別(database identity),之前介紹的Component物件並不是實體,它沒有自已的資料庫識別,具體的話,它沒有id屬性,Hibernate並不會賦予它id值。

 實體與實體之間的關係有:一對一、多對一、一對多、多對多。其中多對一算是最常見的實體關係,舉個簡單的例子,假設您在撰寫一個宿舍管理系統,一般來說,房客與房間之間的關係就是一種多對一的關係,因為一間房間可以分配給多個人(學生宿舍啦,一般應該都是二到八個人不等吧!看學校的環境了)。

 用程式來表示的話,首先看看Room類別的撰寫,我們只簡單的設定位址屬性於其中:

Room.java
package onlyfun.caterpillar;

public class Room {
    private long id;
    private String address;
   
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }   
   public String getAddress() {
       return address;
   }
   public void setAddress(String address) {
       this.address = address;
   }
}

 注意這個類別與Component物件不同的是,它擁有id屬性,在儲存至資料庫,Hibernate會賦予值給它;房客的話我們設計一個User類別:

User.java
package onlyfun.caterpillar;

public class User {
    private long id;
    private String name;
    private Room room;
   
    public long getId() {
        return id;
    }
    public void setId(long 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;
    }
}

 在Java中,一個Room物件可以被多個User物件參考,也就是說User對Room的關係是多對一的關係,我們也可以反過來設計Room對 User的關係,將其設計為一對多,這在下一個主題中討論,現階段我們先關注多對一的映射,我們的Room映射文件Room.hbm.xml很簡單,如下:

Room.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

    <class name="onlyfun.caterpillar.Room" table="ROOM">

        <id name="id" column="ROOM_ID">
            <generator class="increment"/>
        </id>

        <property name="address" type="string"/>
    </class>

</hibernate-mapping>

 再來是User.hbm.xml的撰寫,我們使用<many-to-one>來設定多對一映射關係,如下:

User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

    <class name="onlyfun.caterpillar.User" table="USER">

        <id name="id" column="USER_ID">
            <generator class="increment"/>
        </id>

        <property name="name">
            <column name="NAME" length="16" not-null="true"/>
        </property>
     
        <many-to-one name="room"
                     column="ROOM_ID"
                     class="onlyfun.caterpillar.Room"/>
    </class>

</hibernate-mapping>

 與User對應的USER表格是透過ROOM_ID的值參考至ROOM表格,當然,最重要的別忘了在hibernate.cfg.xml中指定映射文件的位置與名稱:

hibernate.cfg.xml
<?xml version='1.0' encoding='big5'?>
<!DOCTYPE hibernate-configuration
    PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

<hibernate-configuration>

    <session-factory>

        ......

        <!-- 物件與資料庫表格映射文件 -->
        <mapping resource="Room.hbm.xml"/>
        <mapping resource="User.hbm.xml"/>

    </session-factory>

</hibernate-configuration>

 我們用下面這個程式簡單的測試一下儲存的結果:

HibernateTest.java
import onlyfun.caterpillar.*;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

public class HibernateTest {
    public static void main(String[] args) throws HibernateException {
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
     
        Room room1 = new Room();
        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(room1);
        session.save(room2);
        session.save(user1);
        session.save(user2);
        session.save(user3);

        tx.commit();
        session.close();

        sessionFactory.close();
    }
}

 直接來看看儲存在資料庫中是什麼樣子:

mysql> select * from USER;
+---------+-------------+---------+
| USER_ID | NAME        | ROOM_ID |
+---------+-------------+---------+
|       1 | bush        |       1 |
|       2 | caterpillar |       1 |
|       3 | momor       |       2 |
+---------+-------------+---------+
3 rows in set (0.00 sec)

mysql> select * from ROOM;
+---------+------------+
| ROOM_ID | address    |
+---------+------------+
|       1 | NTU-M8-419 |
|       2 | NTU-G3-302 |
+---------+------------+
2 rows in set (0.00 sec)

抱歉!评论已关闭.