gpt4 book ai didi

java - 如何用JPA注解Map

转载 作者:搜寻专家 更新时间:2023-10-31 08:25:40 26 4
gpt4 key购买 nike

我有这张 map :

Map<Owner, Integer> ownerSharesMap = new HashMap<>();

我知道如何将 HashMap@OneToMany 关系进行映射,该关系以原始类型作为键,但我在 google 上搜索了很多并没有找到映射的方法上面的 HashMap 与 JPA。不过,我看到了两个选项:

将我的 HashMap 更改为:(其中 uuid 是 Owner 的键列)

Map<UUID, Integer> ownerIdSharesMap = new HashMap<>();

或者创建一个这样的类:

public class Share{
int count;
Owner owner
}

然后持久化这个集合:

Set<Share> shares;

你有什么建议?有没有办法用 JPA 注释第一个 Map 还是我应该使用后面的解决方案?

请注意,在我的项目中,查询性能是主要关注点,但我也想要干净的 OOD。

谢谢。

最佳答案

这在 JPA 中是可能的。

map 集合中的值不是实体,因此您需要使用 @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

@ElementCollection
@CollectionTable(name = "OWNER_SHARES", joinColumns = @JoinColumn(name = "SHARE_ID") )
@Column(name="SHARE_AMOUNT")
private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();

按实体键控时,并非实体的所有属性都会存储在集合表中。它只是将要存储的实体的主键。为此,我们将在集合表中增加一列来存储 map 的键,即 Owner 实体主键的外键。要覆盖此列的名称,您可以使用 @MapKeyJoinColumn

@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>();

如果不指定@MapKeyJoinColumn,则默认的列名将是元素集合属性的名称,并附加字符串“_KEY”。因此,在我们的示例中,这将是 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>();
...
}

下面是保存实体及其集合的示例代码:

    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();

下面是 Hibernate 如何在 MySQL 中生成模式:

Hibernate: 
create table OWNER (
OWNER_ID integer not null auto_increment,
primary key (OWNER_ID)
)
Hibernate:
create table OWNER_SHARES (
SHARE_ID integer not null,
SHARE_AMOUNT integer,
OWNER_KEY integer not null,
primary key (SHARE_ID, OWNER_KEY)
)
Hibernate:
create table SHARE (
SHARE_ID integer not null auto_increment,
primary key (SHARE_ID)
)
Hibernate:
alter table OWNER_SHARES
add constraint FK_th03t34g0d8hj7hmhppaa9juk
foreign key (OWNER_KEY)
references OWNER (OWNER_ID)
Hibernate:
alter table OWNER_SHARES
add constraint FK_smwhicxpq0ydqan5jn1p3goom
foreign key (SHARE_ID)
references SHARE (SHARE_ID)

表格中的数据如下所示:

enter image description here

您将在我的 GitHub repo 中看到此实现的示例.

关于java - 如何用JPA注解Map<Entity,INTEGER>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33267131/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com