一.前言
多对多在我们生活中也存在很多.比如:一个老师可以有多个学生,一个学生也对应多个任课老师
一个商品类对应多个商品,一个商品可以对应多个类.比如可口可乐可以属于休闲零食类,也可以属于酒水饮料类.
二.单向多对多
多对多必须使用中间关联表
商品类Cgoods:
public class Cgoods {
private Integer cgoodsId;//商品类编号
private String cgoodsName;//商品类名称
private Set<Items> items=new HashSet<>();//商品项目集合
public Integer getCgoodsId() {
return cgoodsId;
}
public void setCgoodsId(Integer cgoodsId) {
this.cgoodsId = cgoodsId;
}
public String getCgoodsName() {
return cgoodsName;
}
public void setCgoodsName(String cgoodsName) {
this.cgoodsName = cgoodsName;
}
public Set<Items> getItems() {
return items;
}
public void setItems(Set<Items> items) {
this.items = items;
}
}
商品项目类Items:
public class Items {
private int itemId;//单个商品的id
private String itemName;//商品的名称
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
}
生成的xml文件
Cgoods.hbm.xml
<hibernate-mapping package="com.eduask.chp.many2many">
<class name="Cgoods" table="CGOODS">
<id name="cgoodsId" type="java.lang.Integer">
<column name="CGOODS_ID" />
<generator class="native" />
</id>
<property name="cgoodsName" type="java.lang.String">
<column name="CGOODS_NAME" />
</property>
<!-- table 指定中间表 -->
<set name="items" table="Cgoods_ITEMS">
<key>
<column name="C_ID" />
</key>
<many-to-many class="Items" column="I_ID"></many-to-many>
</set>
</class>
</hibernate-mapping>
Items.hbm.xml
<hibernate-mapping>
<class name="com.eduask.chp.many2many.Items" table="ITEMS">
<id name="itemId" type="int">
<column name="ITEM_ID" />
<generator class="native" />
</id>
<property name="itemName" type="java.lang.String">
<column name="ITEM_NAME" />
</property>
</class>
</hibernate-mapping>
三.双向多对多
双向 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, 否则两端都维护关联关系可能会造成主键冲突.
Cgoods类不变
Items类加一个S
et<Cgoods>
public class Items {
private int itemId;//单个商品的id
private String itemName;//商品的名称
private Set<Cgoods> cgoods=new HashSet<>();
public Set<Cgoods> getCgoods() {
return cgoods;
}
public void setCgoods(Set<Cgoods> cgoods) {
this.cgoods = cgoods;
}
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
}
Items.hbm.xml
<hibernate-mapping package="com.eduask.chp.many2many">
<class name="Items" table="ITEMS">
<id name="itemId" type="int">
<column name="ITEM_ID" />
<generator class="native" />
</id>
<property name="itemName" type="java.lang.String">
<column name="ITEM_NAME" />
</property>
<set name="cgoods" table="Cgoods_ITEMS" inverse="true" >
<key column="I_ID">
</key>
<many-to-many class="Cgoods" column="C_ID"></many-to-many>
</set>
</class>
</hibernate-mapping>
两者对比下,交叉设定
Cgoods.hbm.xml
Items.hbm.xml