用于搜索的HQL查询(一对多关系)

sue*_*nda 3 entity hibernate hql one-to-many

我有两个实体,书和作者。

@Entity
@Table(name="book") 
class Book {
    private int id;
    private Map<Integer, Author> authors = new HashMap<Integer, Author>();

    @Id
    @GeneratedValue
    @Column(name="id_book")
    public int getId() {
        return this.id;
    }

    @OneToMany(fetch=FetchType.EAGER)
    @JoinTable(name="book_author", joinColumns= {@JoinColumn(name="id_book")},
            inverseJoinColumns = {@JoinColumn(name="id_author", table="author")})
    @MapKeyColumn(name="order")
    public Map<Integer, Author> getAuthors() {
        return authors;
    }


}

@Entity
@Table(name="author")
class Author {

    private int id;
    private String lastname;
    private String firstname;

    @Id
    @Column(name="id_author")
    @GeneratedValue
    public int getId() {
        return id;
    }

    public String getLastname() {
        return lastname;
    }

    public String getFirstname() {
        return firstname;
    }

}
Run Code Online (Sandbox Code Playgroud)

一本书中有许多作者按特定顺序列出。现在,我正在尝试创建一个HQL,以便可以从具有特定名字或姓氏或二者兼有的特定作者那里获得书籍清单。我对如何在两个实体之间使用联接感到困惑。任何的想法?

提前致谢。

Joh*_*nna 5

第一:您在书籍和作者之间存在一对多的关系。一本书可以有很多作者,但是一位作者只能写一本书。如果一个真实的人写了许多书,那么他需要在表格作者中排很多行,每本他的书都需要一行。这可能不是您想要的,但是您已经定义了这种关系。

一对多关系在数据库方面与表作者中的书的ID一起工作。请在Java中使用该ID创建一个getter getBookID()Author。然后,您可以使用HQL语句

from Book b inner join Author a 
   where b.id  = a.bookId
      and a.lastname = :ln
      and a.firstname = :fn
Run Code Online (Sandbox Code Playgroud)

要么

from Book b where b.id in (select bookId from Author a
                              where a.lastname = :ln
                              and a.firstname = :fn)
Run Code Online (Sandbox Code Playgroud)

第二:现在您可能希望一位作者可以拥有许多书籍。然后,您具有多对多关系。为此,建议引入一个包含多对多关系的交叉表。此交叉表仅包含两列,即书籍ID和作者ID,并且书籍和作者均与其具有一对多关系(并且作者不再具有bookId)。HQL语句与第一种情况类似,不同之处在于它们遍历了三个表。

编辑:使用Book_Author表:为进行选择,您必须创建一个BookAuthor类,该类映射到该表。然后,您可以使用HQL语句

from Book b inner join BookAuthor ba inner join Author a 
   where b.id  = ba.bookId
      and ba.authorId = a.id
      and a.lastname = :ln
      and a.firstname = :fn
Run Code Online (Sandbox Code Playgroud)

要么

from Book b where b.id in (select ba.bookId from BookAuthor ba, Author a
                              where ba.authorId = a.id
                                 and a.lastname = :ln
                                 and a.firstname = :fn)
Run Code Online (Sandbox Code Playgroud)