Hibernate的一對多關聯

 1CREATE TABLE IF NOT EXISTS Province
 2(
 3   Guid                           INT                            NOT NULL AUTO_INCREMENT,
 4   Provincename                   VARCHAR(16)                    NOT NULL,
 5   PRIMARY KEY (Guid)
 6) TYPE=InnoDB;
 7
 8CREATE TABLE IF NOT EXISTS City
 9(
10   Guid                           INT                            NOT NULL AUTO_INCREMENT,
11   Cityname                       VARCHAR(32)                    NOT NULL,
12   ProvinceID                     INT                            NOT NULL,
13   PRIMARY KEY (Guid)
14) TYPE=InnoDB;
15
16ALTER TABLE City ADD CONSTRAINT CityRFProvince FOREIGN KEY (ProvinceID) 
17   REFERENCES Province (Guid) ON DELETE CASCADE ON UPDATE RESTRICT;

      Province表做爲主控方,City表做爲被控方,兩者之間是雙向的一對多關係。用Middlegen生成的Province.hbm.xml文件,修改後的內容如下:

 1<?xml version="1.0"?>
 2<!DOCTYPE hibernate-mapping PUBLIC
 3    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
 4    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
 5    
 6<hibernate-mapping>
 7<!-- 
 8    Created by the Middlegen Hibernate plugin 2.1
 9
10    http://boss.bekk.no/boss/middlegen/
11    http://www.hibernate.org/
12-->
13
14<class 
15    name="com.xxx.hibernate.Province" 
16    table="Province"
17>
18    <meta attribute="class-description" inherit="false">
19       @hibernate.class
20        table="Province"
21    </meta>
22
23    <id
24        name="guid"
25        type="int"
26        column="Guid"
27    >
28        <meta attribute="field-description">
29           @hibernate.id
30            generator-class="native"
31            type="int"
32            column="Guid"
33
34
35        </meta>
36        <generator class="native" />
37    </id>
38
39    <property
40        name="provincename"
41        type="java.lang.String"
42        column="Provincename"
43        not-null="true"
44        length="16"
45    >
46        <meta attribute="field-description">
47           @hibernate.property
48            column="Provincename"
49            length="16"
50            not-null="true"
51        </meta>    
52    </property>
53
54    <!-- Associations -->
55  
56    <!-- bi-directional one-to-many association to City -->
57    <set
58        name="cities"
59        lazy="true"
60        inverse="true"
61        cascade="save-update"
62    >
63        <meta attribute="field-description">
64           @hibernate.set
65            lazy="true"
66            inverse="true"
67            cascade="save-update"
68
69           @hibernate.collection-key
70            column="ProvinceID"
71
72           @hibernate.collection-one-to-many
73            class="com.xxx.hibernate.City"
74        </meta>
75        <key>
76            <column name="ProvinceID" />
77        </key>
78        <one-to-many 
79            class="com.xxx.hibernate.City"
80        />
81    </set>
82
83</class>
84</hibernate-mapping>
85


      set節點有以下屬性(摘自Hibernate文檔):

(1)

name 集合屬性的名稱

(2)

table (可選——默認爲屬性的名稱)這個集合表的名稱(不能在一對多的關聯關係中使用)

(3)

schema (可選) 表的schema的名稱, 他將覆蓋在根元素中定義的schema

(4)

lazy (可選——默認爲false) lazy(可選--默認爲false) 允許延遲加載(lazy initialization )(不能在數組中使用)

(5)

inverse (可選——默認爲false) 標記這個集合作爲雙向關聯關係中的方向一端。

(6)

cascade (可選——默認爲none) 讓操作級聯到子實體

(7)

sort(可選)指定集合的排序順序, 其可以爲自然的(natural)或者給定一個用來比較的類。

(8)

order-by (可選, 僅用於jdk1.4) 指定表的字段(一個或幾個)再加上asc或者desc(可選), 定義Map,Set和Bag的迭代順序

(9)

where (可選) 指定任意的SQL where條件, 該條件將在重新載入或者刪除這個集合時使用(當集合中的數據僅僅是所有可用數據的一個子集時這個條件非常有用)

(10)

outer-join(可選)指定這個集合,只要可能,應該通過外連接(outer join)取得。在每一個SQL語句中, 只能有一個集合可以被通過外連接抓取(譯者注: 這裏提到的SQL語句是取得集合所屬類的數據的Select語句)

(11)

batch-size (可選, 默認爲1) 指定通過延遲加載取得集合實例的批處理塊大小("batch size")。

(12)

access(可選-默認爲屬性property):Hibernate取得屬性值時使用的策略

      由於在建立外鍵的時候就聲明瞭ON DELETE CASCADE,所以在xml的配置文件中cascade聲明爲save-update。如果聲明爲all,那麼在刪除Province表的數據時,會無謂的多出一條刪除City的delete語句出來,這將會影響程序的性能。
      City.hbm.xml的內容如下:

 1<?xml version="1.0"?>
 2<!DOCTYPE hibernate-mapping PUBLIC
 3    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
 4    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
 5    
 6<hibernate-mapping>
 7<!-- 
 8    Created by the Middlegen Hibernate plugin 2.1
 9
10    http://boss.bekk.no/boss/middlegen/
11    http://www.hibernate.org/
12-->
13
14<class 
15    name="com.xxx.hibernate.City" 
16    table="City"
17>
18    <meta attribute="class-description" inherit="false">
19       @hibernate.class
20        table="City"
21    </meta>
22
23    <id
24        name="guid"
25        type="int"
26        column="Guid"
27    >
28        <meta attribute="field-description">
29           @hibernate.id
30            generator-class="native"
31            type="int"
32            column="Guid"
33
34
35        </meta>
36        <generator class="native" />
37    </id>
38
39    <property
40        name="cityname"
41        type="java.lang.String"
42        column="Cityname"
43        not-null="true"
44        length="32"
45    >
46        <meta attribute="field-description">
47           @hibernate.property
48            column="Cityname"
49            length="32"
50            not-null="true"
51        </meta>    
52    </property>
53
54    <!-- Associations -->
55  
56    <!-- bi-directional many-to-one association to Province -->
57    <many-to-one
58        name="province"
59        class="com.xxx.hibernate.Province"
60        cascade="none"
61        outer-join="auto"
62        update="true"
63        insert="true"
64        access="property"
65        not-null="true"
66    >
67        <meta attribute="field-description">
68           @hibernate.many-to-one
69            cascade="none"
70            outer-join="auto"
71            update="true"
72            insert="true"
73            access="property"
74            not-null="true"
75           @hibernate.column name="ProvinceID"         
76        </meta>
77        <column name="ProvinceID" />
78    </many-to-one>
79
80</class>
81</hibernate-mapping>
82


      many-to-one節點有以下屬性(摘自Hibernate文檔):

(1)

name: 屬性名。

(2)

column (可選): 字段名。

(3)

class (可選 - 默認是通過反射得到屬性類型): 關聯的類的名字。

(4)

cascade(級聯) (可選): 指明哪些操作會從父對象級聯到關聯的對象。

(5)

outer-join(外連接) (可選 - 默認爲 自動): 當設置hibernate.use_outer_join的時候,對這個關聯允許外連接抓取。

(6)

update, insert (可選 - defaults to true) 指定對應的字段是否在用於UPDATE 和/或 INSERT的SQL語句中包含。如果二者都是false,則這是一個純粹的“外源性(derived)”關聯,它的值是通過映射到同一個(或多個)字段的某些其他屬性得到的,或者通過trigger(除法器),或者是其他程序。

(7)

property-ref: (可選) 指定關聯類的一個屬性,這個屬性將會和本外鍵相對應。如果沒有指定,會使用對方關聯類的主鍵。

(8)

access (可選 - 默認是 property): Hibernate用來訪問屬性的策略。

cascade 屬性允許下列值: all, save-update, delete, none。設置除了none以外的其它值會傳播特定的操作到關聯的(子)對象中。參見後面的“Lifecycle Objects(自動管理生命週期的對象)”。

outer-join參數允許下列三個不同值:

  • auto (默認) 使用外連接抓取關聯(對象),如果被關聯的對象沒有代理(proxy)

  • true 一直使用外連接來抓取關聯

  • false 永遠不使用外連接來抓取關聯

      用hbm2java生成對應的對應的Java類:hbm2java *.xml --output=xxx。
      Hibernate的配置文件hibernate.cfg.xml內容如下:


      JUnit的測試用例程序片斷如下:

 1<?xml version="1.0" encoding="utf-8"?>
 2<!DOCTYPE hibernate-configuration
 3    PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
 4    "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
 5
 6<hibernate-configuration>
 7    <session-factory>
 8
 9        <!-- local connection properties -->
10        <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1/xxx?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true</property>
11        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
12        <property name="hibernate.connection.username">root</property>
13        <property name="hibernate.connection.password">123456</property>
14        <!-- property name="hibernate.connection.pool_size"></property -->
15
16        <!-- dialect for MySQL -->
17        <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
18
19        <property name="hibernate.show_sql">true</property>
20        <property name="hibernate.use_outer_join">true</property>
21        <property name="hibernate.transaction.factory_class">net.sf.hibernate.transaction.JDBCTransactionFactory</property>
22        
23        <mapping resource="com/xxx/hibernate/City.hbm.xml"/>
24        <mapping resource="com/xxx/hibernate/Province.hbm.xml"/>
25
26    </session-factory>
27</hibernate-configuration>

 

 1    public void testInsert() {
 2        try {
 3            Province province = new Province();
 4            province.setProvincename("廣東");
 5            
 6            City city = new City();
 7            city.setCityname("深圳");
 8            
 9            city.setProvince(province);
10            province.setCities(new HashSet());
11            province.getCities().add(city);
12            
13            Transaction tx = session.beginTransaction();
14            session.save(province);
15            tx.commit();
16        } catch (HibernateException e) {
17            e.printStackTrace();
18        } catch (Exception ex) {
19            ex.printStackTrace();
20        }
21    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章