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

时间:2013-01-14 01:07:38

标签: hibernate entity 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;
    }

}

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

提前致谢。

1 个答案:

答案 0 :(得分:4)

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

一对多关系在数据库端工作,表作者的书名为id。通过在getBookID()中创建getter Author,在Java中提供此ID。然后您可以使用HQL语句

from Book b inner join Author a 
   where b.id  = a.bookId
      and a.lastname = :ln
      and a.firstname = :fn

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

第二:现在你可能更喜欢一个作者可以有很多书。然后你有一个多对多的关系。为此,建议引入包含多对多关系的交叉表。此交叉表仅包含两列,即书籍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

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)