码迷,mamicode.com
首页 > Web开发 > 详细

Hibernate多对多关联关系

时间:2016-01-21 22:56:16      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:

  前两篇说了 Hibernate 的一对一和一对多, 这一篇说一下 Hibernate 关联关系中的多对多. 说完这个Hibernate的关联关系就结束了.

分类:

  1. 单向多对多

  2. 双向多对多

  要想实现多对多关系, 必须提供中间表, 用外键的方式无法实现.

  这里咱们用 分类(Category)和单品(Item) 来举例子.

OneByOne

  一: 单向多对多

  准备工作:

    1. 建立持久化类

      Category类:

package com.single.many2many;

import java.util.HashSet;
import java.util.Set;

public class Category {

    private Integer id;
    private String name;

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

    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;
    }

}

 

       Item类:

package com.single.many2many;

public class Item {

    private Integer id;
    private String name;

    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;
    }

}

    2. 建立映射文件

      Category.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.single.many2many">
    <class name="Category" table="CATEGORYS">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="identity" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
        <!-- 
            table: 中间表表名
            <key column="C_ID"></key>:
                本数据表在中间表中的列名
            <many-to-many class="Item" column="I_ID"></many-to-many>:
                集合中元素的数据表在中间表中的列名
        -->
        <set name="items" table="CATEGORY_ITEMS">
            <key column="C_ID"></key>
            <many-to-many class="Item" column="I_ID"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

      Item.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.single.many2many">
    <class name="Item" table="ITEMS">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="identity" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>

    </class>
</hibernate-mapping>

 

    3. 建立Hibernate的主配置文件 hibernate.cfg.xml, 并把 Item.hbm.xml, Category.hbm.xml 加入到 配置文件中.

    4. 建立单元测试类:

package com.single.many2many;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestHibernate {
    
    private SessionFactory sessionFactory;
    private Session session;
    private Transaction transaction;
    
    @Before
    public void init(){
        sessionFactory = new Configuration().configure().buildSessionFactory();
        session = sessionFactory.openSession();
        transaction = session.beginTransaction();
    }
    
    @After
    public void distory(){
        transaction.commit();
        session.close();
        sessionFactory.close();
    }
}

 

    1. 测试保存数据

    @Test
    public void testInsert(){
        
        Category category1 = new Category();
        category1.setName("Category-01");
        
        Item item1 = new Item();
        item1.setName("item-01");
        Item item2 = new Item();
        item2.setName("item-02");
        Item item3 = new Item();
        item3.setName("item-03");
        
        // 设置关联关系
        category1.getItems().add(item1);
        category1.getItems().add(item2);
        category1.getItems().add(item3);
        
        session.save(item1);
        session.save(item2);
        session.save(item3);
        session.save(category1);
        
    }

    2. 测试查询数据

    @Test
    public void testQuery(){
        
        Category category = session.get(Category.class, 1);
        System.out.println(category.getName());
        
        // 会连接中间表进行查询
        System.out.println(category.getItems().iterator().next().getName());
        System.out.println(category.getItems().size());
        
    }

 

    3. 测试删除数据(略)

    4. 测试更新数据(略)

 

  二: 双向多对多

    双向多对多与单向多对多差不多, 在单向多对多中我们在 Category类中添加了 Item 的集合, 现在我们不仅在 Category类中添加了 Item 的集合, 还要在 Item类中添加了 Category的集合.

    在上面的测试基础上修改几个地方:

    1. 修改 Item 类:

package com.single.many2many;

import java.util.Set;

public class Item {

    private Integer id;
    private String name;

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

    // getter/setter...

}

 

    2. 修改 Item.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.single.many2many">
    <class name="Item" table="ITEMS">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="identity" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
    
        <!-- 
            双向 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的 cloumn值为a, many-to-many 的 column 为b; 
            则另一边的 set 元素的 key 的 column 值 b,many-to-many的 column 值为 a. 
            对于双向 n-n 关联, 必须把其中一端的 inverse 设置为 true, 
            否则两端都维护关联关系可能会造成主键冲突. 
        -->
        <set name="categories" table="CATEGORY_ITEMS">
            <key column="I_ID"></key>
            <many-to-many class="Category" column="C_ID"></many-to-many>
        </set>
        
    </class>
</hibernate-mapping>

 

    xml中的说明我感觉应该挺详细了. 如果不懂可以给我发消息.

    1. 测试保存数据

    @Test
    public void testSave(){
        
        Category category1 = new Category();
        category1.setName("Category-04");
        Category category2 = new Category();
        category2.setName("Category-05");
        Category category3 = new Category();
        category3.setName("Category-06");
        
        Item item1 = new Item();
        item1.setName("item-04");
        Item item2 = new Item();
        item2.setName("item-05");
        Item item3 = new Item();
        item3.setName("item-06");
        
        category1.getItems().add(item1);
        category1.getItems().add(item2);
        
        item1.getCategories().add(category1);
        item2.getCategories().add(category1);
        item2.getCategories().add(category2);
        item2.getCategories().add(category3);
        
        session.save(item1);
        session.save(item2);
        session.save(item3);
        session.save(category1);
        session.save(category2);
        session.save(category3);
        
    }

 

    2. 测试查询数据(同单向多对多)

    3. 测试删除数据(略)

    4. 测试更新数据(略)

 

    动手敲才是硬道理!

 

Hibernate多对多关联关系

标签:

原文地址:http://www.cnblogs.com/wuqinglong/p/5149311.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!