3

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

@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,以便我可以从具有特定名字或姓氏或两者的特定作者那里获取书籍列表。我对如何在两个实体之间使用连接感到困惑。任何想法?

提前致谢。

4

1 回答 1

7

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

一对多关系在数据库端使用表作者中的书的 id 工作。通过getBookID()Author. 然后您可以使用 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)

第二:现在你可能更喜欢一个作者可以有很多本书。然后你有一个多对多的关系。为此,建议引入包含多对多关系的交叉表。这个交叉表只包含两列,book id 和 author id,并且 Book 和 Author 都有一对多的关系(并且 Author 不再有 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)
于 2013-01-14T11:24:01.983 回答