如:商品对应多个分类 分类对应多个商品
多对多关联关系 需要依赖中间表记录关系
第一个对象(商品分类)
//商品分类
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;
}
}
第二个对象(商品)
//商品
public class Item {
private Integer id;
private String name;
private Set<Category> categories=new HashSet<>();//商品分类集合
public Set<Category> getCategories() {
return categories;
}
public void setCategories(Set<Category> categories) {
this.categories = categories;
}
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;
}
}
第一个对象(商品分类)映射文件
- set元素 table属性指定中间表名
- 子元素key column属性指定当前持久化类在中间表的外键列名称
- 使用many-to-many 指定多对多的关联关系,column指定set集合中的持久化类在中间表的外键列名称
<hibernate-mapping>
<class name="chen.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指定中间表 -->
<set name="items" table="CATEGORY_ITEM">
<!-- column指定当前持久化类在中间表的外键列名称 -->
<key>
<column name="C_ID" />
</key>
<!-- 使用many-to-many 指定多对多的关联关系,column指定set集合中的持久化类在中间表的外键列名称 -->
<many-to-many class="chen.Item" column="I_ID"></many-to-many>
</set>
</class>
</hibernate-mapping>
第二个对象(商品)映射文件
- 几乎一样 调换了key many-to-many的属性值
- 两边都要维护会导致主键重复 所以要设置inverse="true"(两边任意)
<hibernate-mapping>
<class name="chen.Item" table="ITEMS">
<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>
<set name="categories" table="CATEGORY_ITEM" inverse="true">
<key column="I_ID"></key>
<many-to-many class="chen.Category" column="C_ID"></many-to-many>
</set>
</class>
</hibernate-mapping>
保存
/**
* 多对多关联关系 需要中间表 保存
* 两边都要维护会导致主键重复 所以要设置inverse="true"
*/
public static void testManyToManySave() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();// 配置文件configure()
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Category category1=new Category();
category1.setName("电器类");
Category category2=new Category();
category2.setName("小电器");
Category category3=new Category();
category3.setName("男性用品");
Item item=new Item();
item.setName("电动剃须刀");
Item item1=new Item();
item1.setName("蒸蛋器");
//设定关联关系
category1.getItems().add(item);
category2.getItems().add(item);
category3.getItems().add(item);
category1.getItems().add(item1);
category2.getItems().add(item1);
item.getCategories().add(category1);
item.getCategories().add(category2);
item.getCategories().add(category3);
item1.getCategories().add(category1);
item1.getCategories().add(category2);
session.save(category1);
session.save(category2);
session.save(category3);
session.save(item);
session.save(item1);
transaction.commit();
session.close();
sessionFactory.close();
}
查询
- 需要链接中间表 软加载
/**
* 多对多关联关系 查询
*/
public static void testManyToManyGet() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();// 配置文件configure()
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//需要链接中间表 软加载
Category category=session.get(Category.class, 4);
System.out.println(category.getName());
System.out.println(category.getItems().size());
Item item=session.get(Item.class, 3);
System.out.println(item.getName());
System.out.println(item.getCategories().size());
transaction.commit();
session.close();
sessionFactory.close();
}