根据Hibernate documentation,如果我们想将Map用作实体之间的关联,则可以使用多个注释。医生说:
或者,映射键映射到一个或多个专用列。 为了自定义映射,请使用以下之一 注释:
@MapKeyColumn如果地图键是基本类型。如果你没有指定 列名,后跟下划线的属性名称 使用KEY(例如orders_KEY)。 @MapKeyEnumerated / @MapKeyTemporal如果map键类型分别是枚举或Date。 @ MapKeyJoinColumn / @ MapKeyJoinColumns如果地图键类型是另一个 实体。当map键是a时,@ AttributeOverride / @ AttributeOverrides 可嵌入的对象。使用密钥。作为可嵌入对象的前缀 财产名称。您还可以使用@MapKeyClass来定义类型 如果你不使用泛型,那就是关键。
通过一些示例,我能够理解@MapKey仅用于将键映射到目标实体的属性,并且此键仅用于获取记录。 @MapKeyColumn用于将键映射到目标实体的属性,该键用于保存和获取记录。如果这是正确的,请告诉我?
当我需要使用@ MapKeyJoinColumn / @ MapKeyJoinColumns&时,请告诉我。 @MapKeyEnumerated / @MapKeyTemporal
谢谢!
答案 0 :(得分:31)
当您使用Map
时,您始终需要关联至少两个实体。我们假设我们有一个与Owner
实体相关的Car
实体(Car
有一个FK到Owner
)。
因此,Owner
将Map
Car(s)
:
Map<X, Car>
@MapKey
@MapKey
会为您提供Car's
属性,用于将Car
分组到其Owner
。例如,如果vin
中有Car
(车辆识别码)属性,我们可以将其用作carMap
键:
@Entity
public class Owner {
@Id
private long id;
@OneToMany(mappedBy="owner")
@MapKey(name = "vin")
private Map<String, Car> carMap;
}
@Entity
public class Car {
@Id
private long id;
@ManyToOne
private Owner owner;
private String vin;
}
@MapKeyEnumerated
@MapKeyEnumerated
将使用Car
中的枚举,例如WheelDrive
:
@Entity
public class Owner {
@Id
private long id;
@OneToMany(mappedBy="owner")
@MapKeyEnumerated(EnumType.STRING)
private Map<WheelDrive, Car> carMap;
}
@Entity
public class Car {
@Id
private long id;
@ManyToOne
private Owner owner;
@Column(name = "wheelDrive")
@Enumerated(EnumType.STRING)
private WheelDrive wheelDrive;
}
public enum WheelDrive {
2WD,
4WD;
}
这将按照WheelDrive类型对汽车进行分组。
@MapKeyTemporal
@MapKeyTemporal
将使用Date
/ Calendar
字段进行分组,例如createdOn
。
@Entity
public class Owner {
@Id
private long id;
@OneToMany(mappedBy="owner")
@MapKeyTemporal(TemporalType.TIMESTAMP)
private Map<Date, Car> carMap;
}
@Entity
public class Car {
@Id
private long id;
@ManyToOne
private Owner owner;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="created_on")
private Calendar createdOn;
}
@MapKeyJoinColumn
@MapKeyJoinColumn
需要第三个实体,例如Manufacturer
,以便您拥有从Owner
到Car
的关联,并且汽车也与Manufacturer
有关联},以便您可以按Owner's
:
Cars
Manufacturer
进行分组
@Entity
public class Owner {
@Id
private long id;
@OneToMany(mappedBy="owner")
@MapKeyJoinColumn(name="manufacturer_id")
private Map<Manufacturer, Car> carMap;
}
@Entity
public class Car {
@Id
private long id;
@ManyToOne
private Owner owner;
@ManyToOne
@JoinColumn(name = "manufacturer_id")
private Manufacturer manufacturer;
}
@Entity
public class Manufacturer {
@Id
private long id;
private String name;
}
答案 1 :(得分:0)
这是一个将@MapKey与@OneToMany和合成的@IdClass一起使用的工作示例。显然,这不是达到目标的唯一方法,但我认为这是最可维护的。
@Entity
@Table(name = "template_categories")
@IdClass(TemplateCategoryId.class)
public class TemplateCategory implements Serializable {
private static final long serialVersionUID = 1L;
@Id
long orgId;
@Id
long templateId;
@OneToMany(targetEntity = TemplateEntry.class)
@JoinColumns( {
@JoinColumn(name = "orgId", referencedColumnName = "orgId"),
@JoinColumn(name = "templateId", referencedColumnName = "templateId")
}
)
@MapKey(name="key")
private Map<String, TemplateEntry> keyMap;