我正在尝试提高使用 Hibernate 的应用程序的性能,该应用程序对数据库执行过多的 SQL 调用。我认为数据获取可以组合在一起以减少调用并提高性能,但我在这里有点不知所措。我查看了有关子选择和批量提取的 Hibernate 文档,这确实有所帮助,但我认为它并不能完全消除问题。
在下面的示例中,我需要获取作为部队一部分的士兵列表的详细信息并将其显示在网页上。
@Entity
public class Troop {
@OneToMany(mappedBy="troop")
public List<Soldier> getSoldiers() {
...
}
很容易将获取策略设置为子选择、批处理或急切地检索该部队的所有士兵部分,而无需太多 SQL 语句。
@Entity
public class Soldier {
@Id
String soldierId
String firstName;
String lastName;
@OneToMany(mappedBy="address")
public List<Soldier> getAddress() {
...
@OneToMany(mappedBy="combatHistory")
public List<Soldier> getCombatHistory() {
...
@OneToMany(mappedBy="medicalHistory")
public List<Soldier> getMedicalHistory() {
...
}
每个士兵实体与其他延迟加载的实体有多个一对多的关系。我需要初始化这些集合并从中检索值。如果一个士兵有 3 个一对多关系,而一个部队有 1,000 名士兵,这将导致 3 x 1,000 个 SQL 调用!
有没有办法通过减少调用次数来优化它?由于我已经知道我需要检索的士兵 ID,我可以检索实体并将它们放在一级缓存中吗?
例如我可以查询
from Address as a where a.soldierId in (...)
from CombatHistory as a where a.soldierId in (...)
from MedicalHistory as a where a.soldierId in (...)
如果可以缓存 Address、CombatHistory 等实体,则在每个士兵中访问集合时不会执行 SQL 选择。这会将调用次数减少到每个集合一次(在本例中为 3 个),而不是每个士兵每次集合一次(3 x 1000)
我在文档中并没有看到太多关于解决这个问题的内容,因此非常感谢任何提示和想法。请记住,由于这些集合是列表而不是集合,因此无法在多个集合上执行左连接提取,否则 Hibernate 将返回异常。
HibernateException: cannot simultaneously fetch multiple bags