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,加入多个表的主要内容,如果未能解决你的问题,请参考以下文章

直接加入 JPA 或 HIBERNATE

Hibernate/JPA 注释中的多列连接

hibernate jpa将两个表与另一个表连接起来

Hibernate CriteriaBuilder 加入多个表

Hibernate JPA 加入继承

Java - Spring Boot - Hibernate - JPA(@ManyToOne 发布错误)