JPA系列九:映射关联关系-双向多对多

1、创建实体类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、创建实体类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;
	}
}

3、在persistence.xml中配置

 <!-- 添加持久化类 -->
 <class>com.atguigu.jpa.helloworld.Item</class>
 <class>com.atguigu.jpa.helloworld.Category</class>

4、测试:

@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
        (?, ?)
//对于关联的集合对象, 默认使用懒加载的策略.
//使用维护关联关系的一方获取, 还是使用不维护关联关系的一方获取, SQL 语句相同. 
@Test
public void testManyToManyFind(){
	Item item = entityManager.find(Item.class, 2);
	System.out.println(item.getItemName());
	System.out.println(item.getCategories().size());
	
	Category category = entityManager.find(Category.class, 3);
	System.out.println(category.getCategoryName());
	System.out.println(category.getItems().size());
}

JPA系列九:映射关联关系-双向多对多