首先,这是我第一次使用Hibernate,所以我的问题可能看起来很幼稚。
我有两张桌子,DsJobs和DsEvents。事件在DsJobs表上具有外键关系(DsJobs表中的EID列对应于DsEvents表的ID列)。
我用anotations创建了映射,我关心的是单边关系,所以我在DsJobs表中有一个'dsEvents'属性,用@ManyToOne注释:
@Entity
@Table(name="DsJobs")
public class DsJobs implements java.io.Serializable {
...
private DsEvents dsEvents;
...
@Id
@Column(name="JID", unique=true, nullable=false)
public long getJid() {
return this.jid;
}
public void setJid(long jid) {
this.jid = jid;
}
@ManyToOne
@JoinColumn(name="eid")
public DsEvents getDsEvents() {
return this.dsEvents;
}
public void setDsEvents(DsEvents dsEvents) {
this.dsEvents = dsEvents;
}
....
}
我想从数据库中检索Jobs记录列表,并使用setFirstResult和setMaxResults限制它们。这是我的电话:
return (ArrayList<DsJobs>) this.sessionFactory.getCurrentSession().createQuery("from DsJobs log").setFirstResult(start).setMaxResults(rows).list();
此代码返回DsJobs对象的ArrayList,并且在每个DsJobs对象中都有一个DsEvents对象,正确实例化。
我的问题是两个:
当我看到HQL被执行时,会对数据库进行不必要的SELECT调用,每个DsJobs记录一次。因此,对于每个DsJobs记录,DsEvents中有一个SELECT来按事件id获取相应的事件。这对性能来说是不可接受的,因为使用简单的JDBC我可以通过内部连接SELECT stament获得我需要的所有数据。我可能做了一些完全错误的事情,请告诉我什么,如果你知道我该怎么做。
Hibernate似乎完全忽略了setFirstResult和setMaxResults,我总是从数据库中获取所有记录。我该如何解决这个问题?
我将非常感谢任何帮助。
提前谢谢。
答案 0 :(得分:1)
当我看到HQL被执行时,对数据库进行了不必要的SELECT调用,每个DsJobs记录都有一个。
是的,这是可怕的n + 1选择问题。只有在对关系强制执行某些RI约束时才会发生这种情况(例如,一对一或唯一约束)。您向我们展示的映射似乎没有出现这些问题,这让我觉得您没有向我们展示导致您遇到麻烦的实际映射。请发布实际代码,而不是它的一些通用缩写版本。
Hibernate似乎完全忽略了setFirstResult和setMaxResults,我总是从数据库中获取所有记录。我该如何解决这个问题?
此代码也没问题。这意味着你没有向我们展示导致你麻烦的实际代码。
答案 1 :(得分:0)
对于1,您可能想要了解Lazy / Eager加载。在您的情况下,您似乎希望Eager加载,即一次检索所有数据。有关详细信息,请参阅此Wiki页面:http://community.jboss.org/wiki/AShortPrimerOnFetchingStrategies
对于2,您的使用听起来是正确的。我需要更多细节才能看出它是错误的。