简体   繁体   English

Hibernate JPA,加入多个表

[英]Hibernate JPA, joining multiple tables

I have a very interesting question: How do i join in hibernate if i have 3 tables?我有一个非常有趣的问题:如果我有 3 张桌子,我如何加入 hibernate? Example: Having table A, B, C;示例:有表 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;
      ...
 }

and my native query will look like: "select * from a inner join b inner join c on a.idA = b.idB and b.lastName = c.lastName and a.name = c.name"我的本机查询将如下所示:“在 a.idA = b.idB 和 b.lastName = c.lastName 和 a.name = c.name 上选择 * from a inner join b inner join c”

in hibernate you can use @JoinColum if you wanna join 2 tables, and @JoinTable, if you are joining table A with table C via table B.在休眠中,如果您想加入 2 个表,可以使用 @JoinColum,如果您要通过表 B 将表 A 与表 C 连接起来,则可以使用 @JoinTable。

so in HQL query will look like: "from A a inner join ab as b inner join ac", where所以在 HQL 查询中将如下所示:“从 A a 内连接 ab 作为 b 内连接 ac”,其中

@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;
...
}

but still in this case i dont have a direct access from table A to table C, can anyone explain me how would i get但仍然在这种情况下,我没有从表 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 

in HQL and JPA在 HQL 和 JPA

For JPA to understand your DB structure, you would need to define the relationships as well.为了让 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;
      ...
 }

And then you can do something as simple as然后你可以做一些简单的事情

A a = yourARepository.findById(1);
List<B> bs = a.getBs();
For(B b : bs){
    List<C> cs = b.getCs();
}

That is just a scribe form the top of my head to give you an idea.这只是我头顶上的一个抄写员,给你一个想法。 You might need to do some adjustments.您可能需要进行一些调整。 I can try out and fix it later when I get home.我可以尝试一下,等我回家后再修。 :) :)

Doesn't claim to exactly answer the question but at least to give a clue which might help(Currently I can't comment due to lack of reputation so can only post it this way).并没有声称完全回答了这个问题,但至少提供了一个可能有帮助的线索(目前我由于缺乏声誉而无法发表评论,因此只能以这种方式发布)。

I had some free time to learn how to work with CriteraBuilder and wanted to implement a join between 3 tables.我有一些空闲时间来学习如何使用 CriteraBuilder 并希望实现 3 个表之间的连接。

在此处输入图片说明

The question was to get all the transacs for a user by id.问题是通过 id 获取用户的所有交易。

Sure double join is not required here, as we have idusers in accounts table and accounts and transacs can be simply joined filtering by idusers from accounts.当然这里不需要双重连接,因为我们在帐户表中有 idusers,并且帐户和交易可以简单地通过帐户中的 idusers 过滤。 Nevertheless it allows to show how I've tackled the join of 3 tables.尽管如此,它允许展示我如何处理 3 个表的连接。

Code with 2 joins where pIdusers is idusers passed to my method and session is a Session got from SessionFactory:带有 2 个连接的代码,其中pIdusers是传递给我的方法的 idusers,而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();

And the Hibernate entities I've used:以及我使用过的 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;
    ....
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM