使用JPA双向多对多关联关系@ManyToMany

2022-07-14,,,

jpa双向多对多关联关系@manytomany

package com.jpa.helloworld; 
import java.util.hashset;
import java.util.set;
 
import javax.persistence.column;
import javax.persistence.entity;
import javax.persistence.generatedvalue;
import javax.persistence.id;
import javax.persistence.manytomany;
import javax.persistence.table;
 
@table(name="categorys")
@entity
public class category { 
	private integer cid; 
	private string cname; 
	private set<item> items = new hashset<item>();
 
	@id
	@column(name="c_id")
	@generatedvalue
	public integer getcid() {
		return cid;
	}
 
	public void setcid(integer cid) {
		this.cid = cid;
	}
 
	@column(name="c_name")
	public string getcname() {
		return cname;
	}
 
	public void setcname(string cname) {
		this.cname = cname;
	}
	
	//添加了mappedby属性则不能使用@jointable注解
	@manytomany(mappedby="categorys")
	public set<item> getitems() {
		return items;
	}
 
	public void setitems(set<item> items) {
		this.items = items;
	} 
}
package com.jpa.helloworld; 
import java.util.hashset;
import java.util.set;
 
import javax.persistence.column;
import javax.persistence.entity;
import javax.persistence.generatedvalue;
import javax.persistence.id;
import javax.persistence.joincolumn;
import javax.persistence.jointable;
import javax.persistence.manytomany;
import javax.persistence.table;
 
@table(name="items")
@entity
public class item { 
	private integer iid; 
	private string iname; 
	private set<category> categorys = new hashset<category>();
 
	@id
	@generatedvalue
	@column(name="i_id")
	public integer getiid() {
		return iid;
	}
 
	public void setiid(integer iid) {
		this.iid = iid;
	}
 
	@column(name="i_name")
	public string getiname() {
		return iname;
	}
 
	public void setiname(string iname) {
		this.iname = iname;
	}
 
	//使用@jointable注解添加中间表
	//其中name属性设置中间表的表名
	//joincloums属性在中间表中添加的列
	//joincolumns属性:
	//				@joincolumn属性设置中间表中的列名
	//						referencedcolumnname属性指向被映射表的主键(可以没有该属性)
	//@inversejoincolumns另外一张表在中间表中的列
	@jointable(
			name="items_categorys",
//			joincolumns = {@joincolumn(name="item_id",referencedcolumnname="i_id")},
			joincolumns = {@joincolumn(name="item_id")},
//			inversejoincolumns= {@joincolumn(name="category_id", referencedcolumnname="c_id")})
			inversejoincolumns= {@joincolumn(name="category_id")})
	@manytomany
	public set<category> getcategorys() {
		return categorys;
	}
 
	public void setcategorys(set<category> categorys) {
		this.categorys = categorys;
	} 
}

manytomany和onetomany的双向控制

下面我们使用权限管理中role<->account(用户manytomany账号)、role<->domain(用户onetomany权限域)的关系来举例。  

1、manytomany

role表

account表

在两个表的对应属性上添加joincolumns和inversejoincolumns,并且相互交换。

  • joincolumn指定本表在中间表中的列名。
  • inversejoincolumns指定受控方的列名。

在两个类中都加上这两个属性,并且值互换,则能够实现双向控制,即任何一方删除,都会自动删除对应中间表的数据。

2、onetomany以及manytoone

role表

domain表

cascade用来指定级联操作, cascade的值只能从cascadetype.persist(级联新建)、cascadetype.remove(级联删  除)、cascadetype.refresh(级联刷新)、cascadetype.merge(级联更新)中选择一个或多个。还有一个选择是使用cascadetype.all,表示选择全部四项。

如果不指定cascade,默认是空的,那么在删除role的时候,只会把domain表中的role这一列的值删除,而该条记录不删除。

joincolumn需要指定,如果不指定就会在domain表中增加额外的一列,这一列与domain的id一样。经过试验,不指定还会造成级联查找失败,原因未知。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

《使用JPA双向多对多关联关系@ManyToMany.doc》

下载本文的Word格式文档,以方便收藏与打印。