Hibernate JPA,连接多个表

时间:2016-03-20 19:56:18

标签: java mysql hibernate jpa join

我有一个非常有趣的问题:如果我有3个表,我如何加入休眠?示例:具有表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;
      ...
 }

,我的原生查询将如下所示:"从a.idA = b.idB和b.lastName = c.lastName和a.name = c.name&#的内连接b内连接c中选择* 34;

在hibernate中你可以使用@JoinColum,如果你想加入2个表,你可以使用@JoinTable,如果你通过表B加入表A和表C.

所以在HQL查询中看起来像:"来自A内部联接a.b作为b内部联接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中

2 个答案:

答案 0 :(得分:1)

要让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();
}

这只是我头脑中的一位抄写员,可以给你一个想法。您可能需要做一些调整。我回家后可以尝试修理它。 :)

答案 1 :(得分:0)

没有声称要确切回答这个问题,但至少要提供一个可能会有所帮助的线索(目前,由于缺乏声誉,我无法发表评论,因此只能以这种方式发布)。

我有一些空闲时间来学习如何使用CriteraBuilder,并希望实现3个表之间的联接。

enter image description here

问题是按ID获取用户的所有事务处理。

这里肯定不需要双重连接,因为我们在帐户表中有iduser,并且帐户和事务可以简单地通过iduser从帐户进行过滤来加入。 不过,它可以显示我如何解决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;
    ....
}