首先发布在这里......
我通常使用PHP和Symfony与Propel和ActionScript 3(Flex 3)一起开发,使用AMF服务。本周末,我正在尝试使用 Java 和 Hibernate 创建 BlazeDS 应用程序,我开始喜欢Java了! !!
经过本周末的一些研究并使用Eclipse的 Hibernate Synchronizer 插件,创建表格(借口我的术语)的表格看起来相当容易,我正在迅速接近理解这些方面。< / p>
然而,我想知道的是如何为我的数据库开发更全面的架构,特别是在查询,结果和迭代方面。让我说清楚:
如果我有一个作者表,我将创建一个作者类,该类映射到表,带有getter和setter等。这部分看起来在Hibernate方面非常标准。
此外,我可能需要一个Peer类(比如在Propel for PHP中)来做例如返回包含Author实例的List / Array的查询。
所以我会(正在纠正)下面的课程:
作者 - 用getter和setter表示一行。
AuthorsPeer - 例如具有 AuthorsPeer :: getAuthorsByCountry('USA'); 等功能 - AuthorsPeer :: getRetiredAuthors(); 或 AuthorsPeer :: getAuthorsWithSwineFlu(); - ...得到图片。 :) - 返回AuthorsList作为结果......见下一点。
AuthorsList - 具有迭代 getNext(), getPrevious()等功能的作者的集合/列表。
这是它在Hibernate中的意思,还是我错过了情节?我在这里注意到一个设计模式,而没有注意到它?我是否需要像AuthorsList这样的东西,或者Hibernate是否提供通用的解决方案。总而言之,处理这些方面的常态是什么。
另外,如果我有一个Books表,如果我打电话说这些与作者有关 作者myAuthor = Authors :: getAuthor(primaryId,includeBooks); 可以Hibernate处理返回一个我可以使用的结果如下: String title = myAuthor.books [0] .title;
我要问的是,对与Books相关的作者的查询是否会导致Hibernate返回作者的书籍全部嵌套在作者“价值对象”中,准备让我突然进行一些迭代?
提前致谢!
答案 0 :(得分:0)
基本上答案是肯定的,有点。 :)如果您获取单个作者然后访问Books集合,Hibernate将为您延迟加载数据。这实际上并不是最高效的方法,但它对程序员来说很方便。理想情况下,您希望使用HQL(Hibernate查询语言)或其Criteria API之类的东西来执行查询和“急切获取”书籍集合,以便可以使用单个SQL查询加载所有数据。
http://docs.jboss.org/hibernate/stable/core/reference/en/html/queryhql.html
否则,如果您访问的作者说有500本书籍,Hibernate可能会对数据库发出500 + 1个SQL查询,这当然非常慢。如果您想了解更多相关信息,可以通过谷歌“n + 1选择问题”进行阅读。
答案 1 :(得分:0)
大多数问题的答案都是肯定的。您应该仔细研究的是如何在Hibernate中映射一对多关系。在你的情况下,作者是“一个”,书籍是很多。那里描述了Associative mappings。如果您正在使用带有Hibernate的Annotations(我强烈推荐使用XML文件),您可以了解如何与注释here建立关联。
关于hibernate的好处是你不必为管理关系做太多工作。以下是您的作者 - 书籍关系所需内容的代码片段。
@Entity public class Author {
@OneToMany(mappedBy="author")
public List<Book> getBooks() {
return books;
}
...
}
@Entity public class Book {
public String getName() {
return bookName;
}
@ManyToOne
public Author getAuthor() {
return author;
}
...
}
要从表中获取作者,您可以使用 Criteria API或HQL 。我更喜欢Criteria API,因为它符合Java的一般编程感觉(与HQL不同)。但您的偏好可能会有所不同。
旁注:您不应该创建“AuthorsList”类。 Java泛型可以帮到您:
List<Author> myAuthors = new ArrayList<Author>();
//iterate like so
for(Author author: myAuthors) {
//do something with current author
}
//or just grab 1
Author firstAuthor = myAuthors.get(0);
Java处理针对类型的编译时间检查,因此您不必这样做。