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端
实体类和映射文件正常设置