hibernate 多对一,一对多关系
•发布于   •作者 心的方向  •372 次浏览  •来自 博客

Hibernate中怎么表示两个数据表之间的关联关系呢?hibernate中用注解的方式来表示,也可以用xml配置,下面我来讲讲注解方式来表示表之间的关联关系吧。

关联关系分为多种方式,有单向关联,双向关联,一对多表现形式,多对一表现形式,多对多表现形式,下面进一步说明。

1) 一对一外键关联映射(单向)

@OneToOne(cascade=CascadeType.ALL)

@JoinColumn(name="userid",unique=true)

    一对一外键关联,使用@OneToOne,并设置了级联操作。@JoinColum设置了外键的名称为userid(数据库字段名),如果不设置,则默认为另一类的属性名+ _id,外键的值是唯一的(unique)。

@OneToOne:一对一映射。它包含五个属性:  targetEntity:关联的目标类  Cascade:持久化时的级联操作,默认没有  fetch:获取对象的方式,默认EAGER  Optional:目标对象是否允许为null,默认允许  mappedBy:定义双向关联中的从属类。 

 

2) 一对一外键关联映射(双向)

 Class1里与上面一样,  

   Class2:

@OneToOne(mappedBy="class2",cascade=CascadeType.ALL)

一对一双向关联关系,使用@OneToOne

注意:需要加上mappedBy="class2",如果不加上的话,Class2也会生成一个外键(class1_id),mappedby="class2"需要指向与他关联对象的一个属性,说明双向关联关系中,有且仅有一端是作为主体(owner)端存在的,主体端负责维护联接列,对于不需要维护这种关系的从表则通过mappedBy属性进行声明,mappedBy的值指向主体的关联属性

规律:只有是双向关联关系,都加上mappedby 

3)(嵌入式对象)组件映射

将另外一个类成为实体类的一部分进行映射;

注意:1.成为其他实体类一部门的类不要注解为@Entity 实体类!

2. 使用@Embedded 将其类注解即可;

3.组件属性名名为了保证不与实体类属性名冲突,可以使用如下注解:

3.1 使用如下形式:

1

2

3

4

5

6

7

@AttributeOverrides(

        {

            @AttributeOverride(name="xx",column=@Column(name="xxx")),

            @AttributeOverride(name="xx2",column=@Column(name="xxx2")),

 

        }

    )

3.2 在嵌入式对象里,对其属性使用@column进行设置

4)   一对多关联映射(单向)

@OneToMany

@JoinColumn(name="orgid")

/**

 * 一对多注解@OneToMany(单向)

 * 如果只写@OneToMany的话,hibernate会建一张中间表来

 * 维护他们之间的关系,

 * 加上@JoinColumn(name="orgid"),则不会建中间表,他会在

 * 多的一端加上外键orgid,来维护他们之间的关系

 */

5)  一对多关联映射(双向)

一端:

@OneToMany(mappedBy="org")

@JoinColumn(name="orgid")

/**

 * 一对多双向,在一的一端中设置mappedBy

 * 说明多的一端为主导

 * 如果指定了外键字段名称,则多的一端也需要指定相同的字段名称

 */

多端:

@ManyToOne

@JoinColumn(name="orgid")

/**

 * 一对多双向

 * 需要指定外键与一的一端给的外键名称一致,@JoinColumn(name="orgid")

 * 也可以不指定,如果在多的一端不指定,则一的一端也不能指定

 * 否则为生成两个外键

 */

6) 多对一关联映射

在多的一端配置:

@ManyToOne(targetEntity=Organization.class)

@JoinColumn(name="orgid")

//多对一注解@ManyToOne

//targetEntity指定了关联对象

//@JoinColumn(name="orgid")指定生产的外键的字段名,默认是org_id

 

7)  多对多关联映射(单向)

@ManyToMany

/**

 * 多对多映射:注解@ManyToMany(单向)

 * 默认情况下,hibernate会自动的创建一张中间表,

 * 来维护多对多关系

 * 默认中间表的名称 :user_role中间表,字段的名称user_id role_id

 * 如果想更换表名和字段名称,注解如下:

 */

@JoinTable(name="t_u_r",

joinColumns={@JoinColumn(name="u_id")},

inverseJoinColumns={@JoinColumn(name="r_id")}

)

8)  多对多关联映射(双向)  User端

@ManyToMany

/**

 * 多对多映射:注解@ManyToMany(单向)

 * 默认情况下,hibernate会自动的创建一张中间表,

 * 来维护多对多关系

 * 默认中间表的名称 :user_role中间表,字段的名称user_id role_id

 * 如果想更换表名和字段名称,注解如下:

 */

@JoinTable(name="t_u_r",

joinColumns={@JoinColumn(name="u_id")},

inverseJoinColumns={@JoinColumn(name="r_id")}

)

/**

 * @JoinTable(name="t_u_r",

 * 指定中间表的表名

 * joinColumns={@JoinColumn(name="u_id")},

 * 指定当前对象的外键

 * inverseJoinColumns={@JoinColumn(name="r_id")}

 * 指定关联对象的外键

 */

Role端

@ManyToMany(mappedBy="role")

/**

 * 多对多,双向关联映射

 */

级联(cascade)属性

1、           CascadeType.ALL(包括增、删、改、查,联动操作),其实查不算在内,查Fetch 2、CascadeType.MERGE(合并的join)--不重要 3、CascadeType.PERSIST(保存的时候在级联) 4、CascadeType.REFRESH(刷新说明:比如现在我查询出了数据,另外一个人在我查询数据之后,他对数据做了修改,这是才会级联上,hibernate会自动刷新我查询出来的数据) 5、CascadeType.REMOVE (只要在删除操作时才会级联) 6、我们一般都只设置CascadeType.ALL就OK了, 7、Cascade不是必须的,他的作用只是可以让我们快速的开发,我们也可以通过手动增、删、改、查 Fetch捉取策略 1、FetchType.EAGER(渴望的,希望马上得到) a) 一对多关系,比如通过get()方法来get出一的一端,他之后会出一条SQL语句,不会自动去查询多的一端,如果设置FetchType.EAGER,会讲他的关联对象查询出来 b) 如果是load的话,他不会发出SQL语句,因为load支持延迟加载,只有真正获取数据时才会发SQL 2、FetchType.LAZY(懒加载) a) 只有真正获取数据时才发出SQL语句 3、默认是:FetchType.LAZY(一对多) 4、默认是:FetchType.EAGER(多对一) 5、一般使用默认就可以了

一对多单向关联代码如下:

     实体类 类别表

package club.itstu.entity;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

@Entity
public class DataType {
	private Integer id;
	private String describes;
	private String typeName;
	private Set<DataItem> dataItem;

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getDescribes() {
		return describes;
	}
	public void setDescribes(String describe) {
		this.describes = describe;
	}

	public String getTypeName() {
		return typeName;
	}

	public void setTypeName(String typeName) {
		this.typeName = typeName;
	}

	@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
	@JoinColumn(name = "type_id")//指定关联外键
            public Set<DataItem> getDataItem() {
		return dataItem;
	}

	public void setDataItem(Set<DataItem> dataItem) {
		this.dataItem = dataItem;
	}
	
}

实体类 条目表

package club.itstu.entity;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class DataItem {
	private Integer id;
	private String ItemName;

	public DataItem() {
		super();
	}

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getItemName() {
		return ItemName;
	}

	public void setItemName(String itemName) {
		ItemName = itemName;
	}

	
	

}

条目表无需做任何操作,这样就实现了一对多单向关联

0 回复
回到顶部

©2017 Powered by 三十三行伪代码
皖ICP备17005175号-3