单向n-n

n-n的关联必须使用连接表

与1-n映射类似,必须为set集合元素添加key子元素,指定CATEGORIES_ITEMS表

中参照CATEGORIES表的外键为GATEGORY_ID.与1-n关联映射不同的是,建立n-n关联时,集合中的元素使用many-to-many(而不使用one-to-mony).many-to-many子元素的class属性指定items集合中存放的是item对象,column属性指定属性指定CATEGORIES_ITEMS表中参照ITEMS表的外键为ITEM_ID

<set name=”items” table=”CATEGORIES_ITEMS” cascade=”save-update”>

         <key column=”CATEGORY_ID“></key>

         <many-to-many class=”Item” column=”item_id”/>

</set>

 

双向n-n关联

双向n-n关联需要两端都使用集合属性

双向n-n关联必须使用连接表

集合属性应增加key子元素泳衣映射外键列,集合元素里还应增加many-to-many

子元素关联实体类

在双向n-n关联的两边都需指定连接表的表名及外键列的列名,两个集合元素set的table元素的值必须指定 ,而且必须相同。Set元素的两个子元素:key和 many-to-many都必须指定column属性 , 其中,key和many-to-many分别制定本持久化类 和关联类在连接表中的外键列名 ,因此两边的key 与 many-to-many的 column属性交叉相同。

也就是说:一边的set元素的key的column值 为a,many-to-many的column为b;则另一边的set元素的key的column值b,many-to-many的column值为a,

对于双向n-n关联,必须把其中一段的inverse设置为true,否则两端都维护关联关系可能会造成主键冲突。

 

 

package com.atguigu.hibernate.n2n;

 

import java.util.HashSet;

import java.util.Set;

 

public class Category {

         private Integer id;

         private String name;

        

         private Set<Item> items = new HashSet<Item>();

 

         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 Set<Item> getItems() {

                   return items;

         }

 

         public void setItems(Set<Item> items) {

                   this.items = items;

         }       

}

 

package com.atguigu.hibernate.n2n;

 

import java.util.HashSet;

import java.util.Set;

 

public class Item {

        

         private Integer id;

         private String name;

        

         private Set<Category> categories = new HashSet<Category>();

         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 Set<Category> getCategories() {

                   return categories;

         }

         public void setCategories(Set<Category> categories) {

                   this.categories = categories;

         }

}

 

<?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 package="com.atguigu.hibernate.n2n" >

    <class name="Category" table="categories">

       <id name="id" type="integer">

           <column name="id"></column>

           <generator class="native"></generator>

       </id>

       <property name="name" type="string">

           <column name="name"></column>

       </property>  

       <!-- table : 指定中间表 -->

       <set name="items" table="categories_items">

           <key>

              <!-- 当前实体类在中间表中的外键的列名 -->

              <column name="c_id"></column>

           </key>

           <!-- 使用many-to-many 指定多对多的关联关系,

           column 指定Set 集合中的持久化类 在中间表中的外键列名

           -->

           <many-to-many class="Item" column="i_id" />

       </set>

    </class>

</hibernate-mapping>

 

 

<?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="com.atguigu.hibernate.n2n.Item" table="items">

       <id name="id" type="integer">

           <column name="id"></column>

           <generator class="native"></generator>

       </id>

       <property name="name" type="string">

           <column name="name"></column>

       </property>  

      

       <set name="categories" table="categories_items" inverse="true">

           <key column="c_id"/>

           <many-to-many class="com.atguigu.hibernate.n2n.Category" column="c_id" />

       </set>

    </class>

</hibernate-mapping>

 

 

 

package com.atguigu.hibernate.n2n;

 

import java.util.Set;

 

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.service.ServiceRegistryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

public class HibernateTest01 {

        

         private SessionFactory sessionFactory;

         private Session session;

         private Transaction transaction;

        

         @Before

         public void init(){

                   Configuration conf = new Configuration().configure();

                   ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry();

                   sessionFactory = conf.buildSessionFactory(serviceRegistry);

                   session = sessionFactory.openSession();

                   transaction = session.beginTransaction();

         }

         @After

         public void destroy(){

                   transaction.commit();

                   session.close();

                   sessionFactory.close();

         }

         @Test

         public void testSave(){

                   Category category1 = new Category();

                   category1.setName("C-AA");

                   Category category2 = new Category();

                   category1.setName("C-BB");

                  

                   Item item1 = new Item();

                   item1.setName("I-AA");

                  

                   Item item2 = new Item();

                   item2.setName("I-BB");

                  

                   //设定关联关系

                   category1.getItems().add(item1);

                   category1.getItems().add(item2);

                  

                   category2.getItems().add(item1);

                   category2.getItems().add(item2);

                  

                   item1.getCategories().add(category1);

                   item1.getCategories().add(category2);

                  

                   item2.getCategories().add(category1);

                   item2.getCategories().add(category2);

                  

                   session.save(category1);

                   session.save(category2);

                  

                   session.save(item1);

                   session.save(item2);

                   //一共打印输出8条语句 ,两边表中各有两条 ,中间表中有4条记录 一共8条插入语句

         }

        

         @Test

         public void testGet(){

                  

                   Category category = (Category) session.get(Category.class, 1);

                   System.out.println(category.getName());

                  

                   //需要连接中间表

                   Set<Item> items  = category.getItems();

                   System.out.println(items.size());

                  

         }

}