Hibernate(8)_单向n对n

1.n-n 的关联必须使用连接表
与1-n映射类似,必须为set集合元素添加 key 子元素,需要指定中间表
2.实体类
Category.java

public class Category {

    private Integer id;
    private String name;

    private Set<Item> item = new HashSet<>();
    //忽略getter和setter 方法
    ...
}

Item.java

public class Item {

    private Integer id;
    private String name;
    //忽略getter和setter
    ...
}

3.映射文件
Category.hbm.xml

<hibernate-mapping package="com.withXml.manyToMany.entity">

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

        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>

        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>

        <!-- table:中间表  column:Category持久化类在中间表的外键-->
        <set name="item" table="CATEGORY_ITEM">
            <key>
                <column name="C_ID" />
            </key>
           <!-- 使用many-to-many指定多对多的关联关系,column:指定Set集合中的持久化类在中间表的外键列的名称,即Item持久化类在中间表的外键 -->
            <many-to-many class="Item" column="I_ID"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

Item.hbm.xml

<hibernate-mapping package="com.withXml.manyToMany.entity">

    <class name="Item" table="ITEM">

        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>

        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>

    </class>
</hibernate-mapping>

4.CRUD测试
①添加

/**
     * 保存操作
     */
    @Test
    public void testSave(){
        Category category = new Category();
        category.setName("C-AA");
        Category category2 = new Category();
        category2.setName("C-BB");

        Item item = new Item();
        item.setName("I-AA");
        Item item2 = new Item();
        item2.setName("I-BB");

        //设定关联关系
        category.getItem().add(item);
        category.getItem().add(item2);

        category2.getItem().add(item);
        category2.getItem().add(item2);

        //保存操作
        session.save(category);
        session.save(category2);
        session.save(item);
        session.save(item2);
    }

②获取

    @Test
    public void testGet(){
        Category category = (Category) session.get(Category.class, 1);
        System.out.println(category.getName());
        //支持懒加载
        System.out.println(category.getItem());

        //需要连接中间表
        Set<Item> itmes = category.getItem();
        System.out.println(itmes.size());
    }

五.总结
n端
①实体类:在其中的一端设置集合属性,这里在Category里设置了Set集合
②映射文件:使用<se>t元素映射集合属性<key>元素映射字段名称,看起来与1对n相似,不同的是:
n对n:
<set> :元素name属性表示集合属性
<set> :元素table属性表示中间表
<key> :元素column属性指定的是外键,此外键引用的是该实体类所对应的数据表的主键
使用<many-to-many>元素来映射关联关系:
name属性指定另外一端的实体类的全类名,
column属性指定外键,此外建引用的是另一端实体类所对应的数据表的主键

详细如下:

<!-- table:中间表  column:Category持久化类在中间表的外键-->
        <set name="item" table="CATEGORY_ITEM">
            <key column="C_ID"></key>
           <!-- 使用many-to-many指定多对多的关联关系,column:指定Set集合中的持久化类在中间表的外键列的名称,即Item持久化类在中间表的外键 -->
            <many-to-many class="Item" column="I_ID"></many-to-many>
        </set>

1对n
<set> :元素name属性表示集合属性
<set> :元素table属性指定的是n端的数据表
<key> :元素column属性指定的是外键,此外键引用的是该实体类所对应的数据表的主键
使用<one-to-many元素来映射关联关系,class属性指定n端的全类名
详细如下:

 <set name="bks" lazy="false" table="BOOKS" cascade="save-update,delete">
            <key column="PUBLISHER_ID"></key>
            <one-to-many class="com.withXml.oneTomany.entity.Books"/>
        </set>

n端
实体类和映射文件正常设置

原文地址:https://www.cnblogs.com/tengpengfei/p/10453956.html