Hibernate JPA,加入多个表
Posted
技术标签:
【中文标题】Hibernate JPA,加入多个表【英文标题】:Hibernate JPA, joining multiple tables 【发布时间】:2016-07-07 05:41:29 【问题描述】:我有一个非常有趣的问题:如果我有 3 个表,我如何加入 hibernate?示例:有表 A、B、C;
@Entity
public class A
private String name;
private Int idA;
...
@Entity
public class B
private String lastName;
private Int idB;
...
@Entity
public class C
private String name;
private String lastName;
...
我的原生查询将如下所示:“select * from a inner join b inner join c on a.idA = b.idB and b.lastName = c.lastName and a.name = c.name”
在休眠中,如果你想加入 2 个表,你可以使用@JoinColum,如果你通过表 B 加入表 A 和表 C,可以使用 @JoinTable。
所以在 HQL 查询中看起来像:“from A a inner join a.b as b inner join a.c”,其中
@Entity
public class A
...
@OneToMany
@JoinColumn(name="idB", referencedColumnName="idA")
private List<B> b;
...
@ManyToMany
@JoinTable(name = "B",
joinColumns = @JoinColumn(name="idB", referencedColumnName="ioA"),
inverseJoinColumns = @JoinColumn(name="lastName",referencedColumnName="lastName")
)
private List<C> c;
...
但在这种情况下,我仍然没有从表 A 到表 C 的直接访问权限,谁能解释一下我将如何获得
select * from a inner join b inner join c on a.idA = b.idB and b.lastName = c.lastName and a.name = c.name
在 HQL 和 JPA 中
【问题讨论】:
你必须定义一个关系,不是吗? 【参考方案1】:并没有声称完全回答了这个问题,但至少给出了一个可能有帮助的线索(由于缺乏声誉,目前我无法发表评论,所以只能以这种方式发布)。
我有一些空闲时间来学习如何使用 CriteraBuilder,并希望实现 3 个表之间的连接。
问题是通过 id 获取用户的所有事务。
这里确实不需要双重联接,因为我们在帐户表中有 idusers,并且可以简单地通过 idusers 从帐户中过滤加入帐户和事务。 尽管如此,它仍然可以展示我如何处理 3 个表的连接问题。
具有 2 个连接的代码,其中 pIdusers 是传递给我的方法的 iduser,session 是从 SessionFactory 获得的 Session:
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Transacs> cq1 = cb.createQuery(Transacs.class);
Root<Transacs> transacsRoot = cq1.from(Transacs.class);
Join<Transacs, Accounts> transacsAccounts = transacsRoot.join(Transacs_.IDACCOUNTS);
Join<Accounts, Users> accountsUsers = transacsAccounts.join(Accounts_.IDUSERS);
Predicate predicate = cb.equal(accountsUsers.get(Users_.IDUSERS), pIdusers);
cq1.select(transacsRoot).where(predicate);
TypedQuery<Transacs> query = session.createQuery(cq1);
List<Transacs> result = query.getResultList();
以及我使用过的 Hibernate 实体:
@Entity
@Table(name = "users")
public class Users
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idusers", unique = true, nullable = false, insertable = false, updatable = false)
private int idusers;
@OneToMany(mappedBy="idusers")
private Set<Accounts> accounts;
...
@Entity
@Table(name = "accounts")
public class Accounts
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idaccounts", unique = true, nullable = false)
private int idaccounts;
@ManyToOne
@JoinColumn(name="idusers", nullable=false)
private Users idusers;
@OneToMany(mappedBy="idaccounts")
private Set<Transacs> transacs;
...
@Entity
@Table(name = "transacs")
public class Transacs
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idtransacs", unique = true, nullable = false)
private int idtransacs;
@ManyToOne
@JoinColumn(name="idaccounts", nullable=false)
private Accounts idaccounts;
....
【讨论】:
【参考方案2】:为了让 JPA 了解您的数据库结构,您还需要定义关系。
@Entity
public class A
private String name;
private Int idA;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "a")
private List<B> bs = new ArrayList()<>;
...
@Entity
public class B
private String lastName;
private Int idB;
@ManyToOne
private A a;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "b")
private List<C> cs = new ArrayList()<>;
...
@Entity
public class C
private String name;
private String lastName;
@ManyToOne
private B b;
...
然后你可以做一些简单的事情
A a = yourARepository.findById(1);
List<B> bs = a.getBs();
For(B b : bs)
List<C> cs = b.getCs();
那只是我头顶上的一个抄写员,可以给你一个想法。您可能需要进行一些调整。我可以在回家后尝试修复它。 :)
【讨论】:
以上是关于Hibernate JPA,加入多个表的主要内容,如果未能解决你的问题,请参考以下文章