版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/J080624/article/details/78776560
在双向多对多关系中,我们必须指定一个关系维护端(owner side),可以通过 @ManyToMany 注释中指定 mappedBy 属性来标识其为关系维护端。
【1】item与Category
item:category = N:N ,item为关系维护端(主),category为从。
item类如下:
@Table(name="JPA_ITEMS")
@Entity
public class Item {
private Integer id;
private String itemName;
private Set<Category> categories = new HashSet<>();
@GeneratedValue
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="ITEM_NAME")
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
//使用 @ManyToMany 注解来映射多对多关联关系
//使用 @JoinTable 来映射中间表
//1. name 指向中间表的名字
//2. joinColumns 映射当前类所在的表在中间表中的外键
//2.1 name 指定外键列的列名
//2.2 referencedColumnName 指定外键列关联当前表的哪一列
//3. inverseJoinColumns 映射关联的类所在中间表的外键
@JoinTable(name="ITEM_CATEGORY",
joinColumns={@JoinColumn(name="ITEM_ID", referencedColumnName="ID")},
inverseJoinColumns={@JoinColumn(name="CATEGORY_ID", referencedColumnName="ID")})
@ManyToMany
public Set<Category> getCategories() {
return categories;
}
public void setCategories(Set<Category> categories) {
this.categories = categories;
}
}
category类如下:
@Table(name="JPA_CATEGORIES")
@Entity
public class Category {
private Integer id;
private String categoryName;
private Set<Item> items = new HashSet<>();
@GeneratedValue
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="CATEGORY_NAME")
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
@ManyToMany(mappedBy="categories")
public Set<Item> getItems() {
return items;
}
public void setItems(Set<Item> items) {
this.items = items;
}
}
【2】多对多持久化操作
示例代码如下:
//多对多的保存
@Test
public void testManyToManyPersist(){
Item i1 = new Item();
i1.setItemName("i-1");
Item i2 = new Item();
i2.setItemName("i-2");
Category c1 = new Category();
c1.setCategoryName("C-1");
Category c2 = new Category();
c2.setCategoryName("C-2");
//设置关联关系
i1.getCategories().add(c1);
i1.getCategories().add(c2);
i2.getCategories().add(c1);
i2.getCategories().add(c2);
c1.getItems().add(i1);
c1.getItems().add(i2);
c2.getItems().add(i1);
c2.getItems().add(i2);
//执行保存
entityManager.persist(i1);
entityManager.persist(i2);
entityManager.persist(c1);
entityManager.persist(c2);
}
控制台输出如下:
Hibernate:
insert
into
JPA_ITEMS
(ITEM_NAME)
values
(?)
Hibernate:
insert
into
JPA_ITEMS
(ITEM_NAME)
values
(?)
Hibernate:
insert
into
JPA_CATEGORIES
(CATEGORY_NAME)
values
(?)
Hibernate:
insert
into
JPA_CATEGORIES
(CATEGORY_NAME)
values
(?)
Hibernate:
insert
into
ITEM_CATEGORY
(ITEM_ID, CATEGORY_ID)
values
(?, ?)
Hibernate:
insert
into
ITEM_CATEGORY
(ITEM_ID, CATEGORY_ID)
values
(?, ?)
Hibernate:
insert
into
ITEM_CATEGORY
(ITEM_ID, CATEGORY_ID)
values
(?, ?)
Hibernate:
insert
into
ITEM_CATEGORY
(ITEM_ID, CATEGORY_ID)
values
(?, ?)
数据库结果如下:
【3】双向多对多获取操作
先获取非维护关联关系的一方,代码示例如下:
@Test
public void testManyToManyFind(){
Category category = entityManager.find(Category.class, 3);
System.out.println(category.getCategoryName());
System.out.println(category.getItems().size());
}
控制台输出如下:
如果先获取维护关联关系的一方呢?
示例代码如下:
@Test
public void testManyToManyFind(){
Item item = entityManager.find(Item.class, 5);
System.out.println(item.getItemName());
System.out.println(item.getCategories().size());
}
控制台输出如下:
故而总结如下:
对于关联的集合对象, 默认使用懒加载的策略;
使用维护关联关系的一方获取, 还是使用不维护关联关系的一方获取, SQL 语句相同。