我有这张地图:
Map<Owner, Integer> ownerSharesMap = new HashMap<>();
我知道如何将HashMap
与@OneToMany
关系映射为原始类型作为关键字,但我搜索了很多内容并且没有找到方法来映射上面的{{1}与JPA。
我看到两个选择:
将我的HashMap
更改为:(其中uuid是HashMap
的关键列)
Owner
或 创建一个这样的类:
Map<UUID, Integer> ownerIdSharesMap = new HashMap<>();
然后坚持这个Set:
public class Share{
int count;
Owner owner
}
你有什么建议吗?有没有办法用JPA注释第一个Map,还是应该使用后面的解决方案?
请注意,在我的项目中,查询性能是主要问题,但我也想要干净的OOD。
感谢。
答案 0 :(得分:10)
这可以在JPA中使用。
地图集合中的值不是实体,因此您需要使用float
对其进行映射。
您的映射可以很简单:
@ElementCollection
虽然,您可以指定将存储值的集合表。使用@ElementCollection
private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();
注释,您可以指定集合表的名称以及连接列。
@CollectionTable
如果未指定@ElementCollection
@CollectionTable(name="OWNER_SHARES",
joinColumns=@JoinColumn(name="SHARE_ID"))
private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();
,则表名将默认为引用实体的名称,附加下划线和包含元素集合的实体属性的名称。在我们的示例中,这将是@CollectionTable
。连接列默认值类似于引用实体的名称,附加下划线和实体表的主键列的名称。
您可以使用SHARE_OWNERSHARESMAP
注释来指定集合表中哪个列所在的地图集合表的整数值。如果未指定,则默认为@Column
。
OWNERSHARESMAP
按实体键入时,并非实体的所有属性都将存储在集合表中。它只是将要存储的实体的主键。为此,我们将在集合表中添加一个列来存储映射的键,这是Owner实体主键的外键。要覆盖此列的名称,您可以使用@ElementCollection
@CollectionTable(name = "OWNER_SHARES", joinColumns = @JoinColumn(name = "SHARE_ID") )
@Column(name="SHARE_AMOUNT")
private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();
。
@MapKeyJoinColumn
如果未指定@MapKeyJoinColumn,则默认列名称将是元素集合属性的名称,并附加字符串&#34; _KEY&#34;。因此,在我们的示例中,这将是@ElementCollection
@CollectionTable(name="OWNER_SHARES", joinColumns=@JoinColumn(name="SHARE_ID"))
@Column(name="SHARE_AMOUNT")
@MapKeyJoinColumn(name="OWNER_KEY")
private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();
。
以下是您的实体在代码中的样子示例:
OWNERSHARESMAP_KEY
这是一个示例代码,用于保存实体及其集合:
@Entity
@Table(name="OWNER")
public class Owner {
@Id
@Column(name="OWNER_ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer id;
...
}
@Entity
@Table(name = "SHARE")
public class Share {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "SHARE_ID")
private Integer id;
@ElementCollection
@CollectionTable(name = "OWNER_SHARES", joinColumns = @JoinColumn(name = "SHARE_ID") )
@Column(name="SHARE_AMOUNT")
@MapKeyJoinColumn(name = "OWNER_KEY")
private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();
...
}
以下是Hibernate如何在MySQL中生成模式:
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Owner owner1 = new Owner();
Owner owner2 = new Owner();
em.persist(owner1);
em.persist(owner2);
Share share = new Share();
share.getOwnerSharesMap().put(owner1, 20);
share.getOwnerSharesMap().put(owner2, 40);
em.persist(share);
em.getTransaction().commit();
以下是表格中数据的外观:
您将在我的GitHub repo中看到此实现的示例。