如何仅从多对多映射表加载 id?
Posted
技术标签:
【中文标题】如何仅从多对多映射表加载 id?【英文标题】:How to load only ids from Many to Many mapping tables? 【发布时间】:2013-06-04 16:46:33 【问题描述】:在两个表之间有一个映射表的多对多关系中,我怎样才能只加载第二个实体的 ID。
以下是解释我想要在这里实现的目标的示例。 下面是一个示例架构
create table user(
id int PrimaryKey,
name text
)
create table pages (
id int PrimaryKey,
page_name text
)
create table user_page (
id_user int,
id_page int,
PrimaryKey (id_user, id_page)
)
注意:用户表和页表中还有其他列,为简洁起见,我没有在此处列出。
用户实体:
@Entity
@Table(name = "user")
public class User
@id
@column(name="id")
private Integer id;
@column(name="name")
private String name;
...
...
@Entity
@Table(name = "page")
public class Page
@id
@column(name="id")
private Integer id;
@column(name="page_name")
private String name;
...
...
我想要做的是在User
类中添加另一个属性Set<Integer> pageIds
,并为该集合中的用户映射所有页面ID。
如何使用 Hibernate 做到这一点?
【问题讨论】:
【参考方案1】:在User
类中:
@ManyToMany
@JoinTable(
name="user_page",
joinColumns = @JoinColumn(name="id_user"),
inverseJoinColumns = @JoinColumn(name="id_page")
)
public Set<Page> pages;
您可以通过遍历返回的集合来获取 id。默认情况下,集合是延迟加载的(即仅 id)。
编辑:如果您出于某种原因不想映射Page
,可以像这样使用@ElementCollection
:
@ElementCollection
@CollectionTable(name="user_page", joinColumns=@JoinColumn(name="id_user"))
@Column(name="id_page")
public Set<Long> pageIds;
【讨论】:
有什么方法可以在不使用 Page 类的情况下只加载集合中的 ID?即向具有所有 id 的 User 类添加另一个属性 Set当我想同时映射pages
和pageIds
时,我遇到了接受答案的问题。当保存User
时,Hibernate 将使用这两个字段来更改映射表,这可能会导致很多奇怪的行为。
我改为solved this,通过创建pageIds
@Transient
并使用@PostLoad
填充集合:
@ManyToMany
@JoinTable(
name="user_page",
joinColumns = @JoinColumn(name="id_user"),
inverseJoinColumns = @JoinColumn(name="id_page")
)
public Set<Page> pages;
@Transient
public Set<Long> pageIds;
@PostLoad
private void postLoad()
pageIds = pages.stream().map(Page::getId).collect(Collectors.toSet());
【讨论】:
我认为 Hibernate 需要急切地将所有 Page 对象加载到内存中来实现这一点,如果有很多 Page 对象或者 Page 对象有很多关联并且属性。以上是关于如何仅从多对多映射表加载 id?的主要内容,如果未能解决你的问题,请参考以下文章