Hibernate關(guān)系映射4:N-N關(guān)聯(lián)

2018-09-28 14:21 更新

我最近在復(fù)習(xí)一下關(guān)于Hibernate關(guān)系映射的知識(shí),看了書(shū)本的介紹以及視頻。這幾篇博客都是對(duì)學(xué)到知識(shí)的一點(diǎn)總結(jié)。當(dāng)然,這些這是最基本的能夠?qū)崿F(xiàn)關(guān)聯(lián)關(guān)系的配置,在實(shí)際的使用中,還有很多參數(shù)需要根據(jù)情況來(lái)設(shè)置。但也算是對(duì)以后開(kāi)發(fā)過(guò)程中遇到遺忘的地方可以進(jìn)行查閱。

在本文中使用的Demo也都已經(jīng)上傳到github中,里邊有詳細(xì)的運(yùn)行說(shuō)明。Github地址:HibernateRelationMapping

單向N-N關(guān)聯(lián)


N-N關(guān)聯(lián)映射增加一張表才完成基本映射。

與1-N映射相似,必須為set集合元素添加key子元素,指定CATEGORIES_ITEMS表中參照CATEGORIES表的外鍵為CATEGORIY_ID。

與1-N不同的是,建立N-N關(guān)聯(lián)時(shí),集合中的元素使用many-to-many。關(guān)于配置文件的屬性的介紹,將在代碼實(shí)現(xiàn)部分介紹。

域模型

圖1

關(guān)系數(shù)據(jù)模型

圖2

代碼實(shí)現(xiàn)

實(shí)體類(lèi)

public class Category {
    private Integer categoryId;
    private String catregoryName;

    private Set<Item> items = new HashSet<Item>();
  //省去get和set方法
}
public class Item {
    private Integer itemId;
    private String itemName;
    //省去get和set方法
}

Category.hbm.xml

<hibernate-mapping package="com.lihui.hibernate.single_n_n">
    <class name="Category" table="CATEGORIES">
        <id name="categoryId" type="java.lang.Integer">
            <column name="CATEGORY_ID" />
            <generator class="native" />
        </id>
        <property name="catregoryName" type="java.lang.String">
            <column name="CATREGORY_NAME" />
        </property>
        <set name="items" table="CATEGORIES_ITEMS">
            <key>
                <column name="C_ID"></column>
            </key>
            <many-to-many class="Item" column="I_ID"></many-to-many>
        </set>
    </class>
</hibernate-mapping>
  • table:指定中間表
  • many-to-many:指定多對(duì)多的關(guān)聯(lián)關(guān)系
  • column:執(zhí)行set集合中的持久化類(lèi)在中間表的外鍵列的名稱(chēng)

Item.hbm.xml

<hibernate-mapping package="com.lihui.hibernate.single_n_n">
    <class name="Item" table="ITEMS">
        <id name="itemId" type="java.lang.Integer">
            <column name="ITEM_ID" />
            <generator class="native" />
        </id>
        <property name="itemName" type="java.lang.String">
            <column name="ITEM_NAME" />
        </property>
    </class>
</hibernate-mapping>

Junit

@Test
    public void testSave() {
        Category c1 = new Category();
        c1.setCatregoryName("C-AA");

        Category c2 = new Category();
        c2.setCatregoryName("C-BB");

        Item i1 = new Item();
        i1.setItemName("I-AA");
        Item i2 = new Item();
        i2.setItemName("I-BB");

        c1.getItems().add(i1);
        c1.getItems().add(i2);
        c2.getItems().add(i1);
        c2.getItems().add(i2);

        session.save(c1);
        session.save(c2);
        session.save(i1);
        session.save(i2);

    }

雙向N-N關(guān)聯(lián)


雙向N-N關(guān)聯(lián)需要兩端都使用set集合屬性,兩端都增加對(duì)集合屬性的訪問(wèn)。

在雙向N-N關(guān)聯(lián)的兩邊都需指定連接表的表名及外鍵列的列名. 兩個(gè)集合元素 set 的 table 元素的值必須指定,而且必須相同。set元素的兩個(gè)子元素:key 和 many-to-many 都必須指定 column 屬性,其中,key 和 many-to-many 分別指定本持久化類(lèi)和關(guān)聯(lián)類(lèi)在連接表中的外鍵列名,因此兩邊的 key 與 many-to-many 的column屬性交叉相同。也就是說(shuō),一邊的set元素的key的 cloumn值為a,many-to-many 的 column 為b;則另一邊的 set 元素的 key 的 column 值 b,many-to-many的 column 值為 a。
圖3對(duì)于雙向 n-n 關(guān)聯(lián), 必須把其中一端的 inverse 設(shè)置為 true, 否則兩端都維護(hù)關(guān)聯(lián)關(guān)系可能會(huì)造成主鍵沖突。

域模型

圖4

關(guān)系數(shù)據(jù)模型

圖5

代碼實(shí)現(xiàn)

實(shí)體類(lèi)

與上文中實(shí)體類(lèi)相似,但是在Item中增加了category的set集合。

public class Category {
    private Integer categoryId;
    private String catregoryName;

    private Set<Item> items = new HashSet<Item>();
  //省去get和set方法
}
public class Item {
    private Integer itemId;
    private String itemName;
    //省去get和set方法
}

Category.hbm.xml

與上文中相同,不再?gòu)?fù)述。

Item.hbm.xml

<hibernate-mapping package="com.lihui.hibernate.single_n_n">
    <class name="Item" table="ITEMS">
        <id name="itemId" type="java.lang.Integer">
            <column name="ITEM_ID" />
            <generator class="native" />
        </id>
        <property name="itemName" type="java.lang.String">
            <column name="ITEM_NAME" />
        </property>
        <set name="categories" table="CATEGORIES_ITEMS" inverse="true">
            <key>
                <column name="I_ID"></column>
            </key>
            <many-to-many class="Category" column="C_ID"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

Notice

注意要在其中一端加入inverse="true",否則會(huì)造成主鍵沖突。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)