首页 > 代码库 > Hibernate基于注解的双向one-to-many映射关系的实现

Hibernate基于注解的双向one-to-many映射关系的实现

在项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现,但是公司的大部分都是基于注解的,因此自己参考之前的代码捣鼓了基于注解的一对多的映射关系实现。


背景:

一的一端:QingAoCenterInfo:青奥场所信息,

多的一端:QingAoPlaceInfo:青奥场馆信息,

其中一个青奥场所下可以包含多个青奥场馆


one端:QingAoCenterInfo,持有QingAoPlaceInfo的List引用,

通过注解@OneToMany(mappedBy="qingAoCenterInfo",cascade= CascadeType.ALL)


mappedBy定义类之间的双向关系。如果类之间是单向关系,不需要提供定义,如果类和类之间形成双向关系,我们就需要使用这个属性进行定义, 否则可能引起数据一致性的问题。要由One的一方指向Many的一方,并且,这个属性应该等于Many的一方中含有One类的属性的属性名,否则会出错啦

cascadeCascadeType[]类型。该属性定义类和类之间的级联关系

定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,而且这种关系是递归调用的。

举个例子:Order 和OrderItem有级联关系,那么删除QingAoCenterInfo时将同时删除它所对应的QingAoPlaceInfo对象。而如果QingAoPlaceInfo还和其他的对象之间有级联关系,那么这样的操作会一直递归执行下去。

cascade的值只能从CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个。还有一个选择是使用CascadeType.ALL,表示选择全部四项。

package com.yuqiaotech.nttelcom.model;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * 青奥重点场所信息表。
 * 
 */
@Entity(name="QING_AO_CENTER_INFO")
@Table(name="QING_AO_CENTER_INFO")
public class QingAoCenterInfo {
	private Long id;
	private String centerName;	//重点场所名称
	private Long alarmNum;		//告警数
	private String note;		//备注
	private String iconName;	//图标名称
	private String cityName;	//所在城市
	private String type;		//重点场所、活动保障
	private Date createTime;
	private List<QingAoPlaceInfo> qingAoPlaceInfo; //场所拥有的场馆
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	/**
	 * @searchItem
	 * displayType="text"
	 * 
	 * 重点场所名称
	 * @return
	 */
	public String getCenterName() {
		return centerName;
	}
	public void setCenterName(String centerName) {
		this.centerName = centerName;
	}
	/**
	 * 告警数
	 * @return
	 */
	public Long getAlarmNum() {
		return alarmNum;
	}
	public void setAlarmNum(Long alarmNum) {
		this.alarmNum = alarmNum;
	}
	/**
	 * 备注
	 * @return
	 */
	public String getNote() {
		return note;
	}
	public void setNote(String note) {
		this.note = note;
	}
	/**
	 * 图标名称
	 * @return
	 */
	public String getIconName() {
		return iconName;
	}
	public void setIconName(String iconName) {
		this.iconName = iconName;
	}

	public String getCityName() {
		return cityName;
	}

	public void setCityName(String cityName) {
		this.cityName = cityName;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public Date getCreateTime() {
		return createTime;
	}
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	@OneToMany(mappedBy="qingAoCenterInfo",cascade= CascadeType.ALL)
	public List<QingAoPlaceInfo> getQingAoPlaceInfo() {
		return qingAoPlaceInfo;
	}
	public void setQingAoPlaceInfo(List<QingAoPlaceInfo> qingAoPlaceInfo) {
		this.qingAoPlaceInfo = qingAoPlaceInfo;
	}
}


many端:QingAoPlaceInfo,持有QingAoCenterInfo的引用

通过@ManyToOne(fetch=FetchType.LAZY )    @JoinColumn(name="f_center_id")设置关联关系

 @ManyToOne指明QingAoPlaceInfo和QingAoCenterInfo之间为多对一关系,多个QingAoPlaceInfo实例关联的都是同一个QingAoCenterInfo对象

    fetch和lazy是用来定义级联查询的方式:

    fetch:官方文档里对fetch有如下描述,Hibernate3 定义了如下几种抓取策略:

  • 连接抓取(Join fetching):Hibernate 通过在 SELECT 语句使用 OUTER JOIN(外连接)来获得对象的关联实例或者关联集合。

  • 查询抓取(Select fetching):另外发送一条 SELECT 语句抓取当前对象的关联实体或集合。除非你显式的指定 lazy="false" 禁止 延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条 select 语句。

  • 子查询抓取(Subselect fetching):另外发送一条 SELECT 语句抓取在前面查询到(或者抓取到)的所有实体对象的关联集合。除非你显式的指定 lazy="false" 禁止延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条 select 语句。

  • 批量抓取(Batch fetching):对查询抓取的优化方案,通过指定一个主键或外键列表,Hibernate 使用单条 SELECT 语句获取一批对象实例或集合。


package com.yuqiaotech.nttelcom.model;

import java.util.Date;
import java.util.List;

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

/**
 * 场馆信息。
 * 
 */
@Entity(name="QING_AO_PLACE_INFO")
@Table(name="QING_AO_PLACE_INFO")
public class QingAoPlaceInfo {
	private Long id;
	private QingAoCenterInfo qingAoCenterInfo;// 重点场所id
	private String placeName;// 场馆名称
	private String note;// 备注
	private String openStat;// 开通状态
	private Long displayOrder;
	private String cityName;
	private Date createTime;
	private List<QingAoPlaceCdmaSector> qingAoPlaceCdmaSector;//拥有的cdma
	private List<QingAoPlaceLteSector> qingAoPlaceLteSector;//拥有的Lte
	private List<QingAoAp> qingAoAp;							//拥有的Ap
	

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}

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

	@ManyToOne(fetch=FetchType.LAZY )
	@JoinColumn(name="f_center_id")
	public QingAoCenterInfo getQingAoCenterInfo() {
		return qingAoCenterInfo;
	}
	
	public void setQingAoCenterInfo(QingAoCenterInfo qingAoCenterInfo) {
		this.qingAoCenterInfo = qingAoCenterInfo;
	}
	/**
	 * @searchItem
	 * displayType="text"
	 * 场所名称
	 * @return
	 */
	public String getPlaceName() {
		return placeName;
	}
	public void setPlaceName(String placeName) {
		this.placeName = placeName;
	}

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	}

	public String getOpenStat() {
		return openStat;
	}

	public void setOpenStat(String openStat) {
		this.openStat = openStat;
	}

	public Long getDisplayOrder() {
		return displayOrder;
	}

	public void setDisplayOrder(Long displayOrder) {
		this.displayOrder = displayOrder;
	}

	public String getCityName() {
		return cityName;
	}

	public void setCityName(String cityName) {
		this.cityName = cityName;
	}
	public Date getCreateTime() {
		return createTime;
	}
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	@OneToMany(mappedBy="qingAoPlaceInfo",cascade= CascadeType.ALL)
	public List<QingAoPlaceCdmaSector> getQingAoPlaceCdmaSector() {
		return qingAoPlaceCdmaSector;
	}

	public void setQingAoPlaceCdmaSector(
			List<QingAoPlaceCdmaSector> qingAoPlaceCdmaSector) {
		this.qingAoPlaceCdmaSector = qingAoPlaceCdmaSector;
	}
	@OneToMany(mappedBy="qingAoPlaceInfo",cascade= CascadeType.ALL)
	public List<QingAoPlaceLteSector> getQingAoPlaceLteSector() {
		return qingAoPlaceLteSector;
	}

	public void setQingAoPlaceLteSector(
			List<QingAoPlaceLteSector> qingAoPlaceLteSector) {
		this.qingAoPlaceLteSector = qingAoPlaceLteSector;
	}
	@OneToMany(mappedBy="qingAoPlaceInfo",cascade= CascadeType.ALL)
	public List<QingAoAp> getQingAoAp() {
		return qingAoAp;
	}

	public void setQingAoAp(List<QingAoAp> qingAoAp) {
		this.qingAoAp = qingAoAp;
	}
}




Hibernate基于注解的双向one-to-many映射关系的实现