【问题标题】:Dynamic Eager & Lazy Loading in HibernateHibernate 中的动态渴望和延迟加载
【发布时间】:2016-05-02 15:09:51
【问题描述】:

我是 Hibernate 的新手,但对 C# 中的实体框架有丰富的经验。我喜欢的一个功能是能够动态决定在查询中立即加载什么。例如,考虑班级和学生实体的一对多关系。

在“查看课程”页面上,我可以这样做:

context.Configuration.EnableLazyLoading = true; //default option
List<Classes> classes = context.Classes.ToList();

现在我可以很高兴地只显示班级信息,而不会浪费资源收集学生数据。仅当用户单击“查看带有名册的班级”时,我才会执行以下操作:

context.Configuration.EnableLazyLoading = true;
List<Classes> classes = context.Classes.Include(c => c.Students).ToList();

通过这句话,我能够决定在这种特殊情况下,我想立即获取所有信息。不是两个查询。不是一百个查询。只需一个查询。尽管只加载了几秒钟前的类。

我在 Hibernate 上的所有阅读都解释了如何在关系的配置文件中指定lazy="true|false",但我真的想要决定何时动态加载集合的选项。毕竟,我对购买时速仅为 30 英里或 60 英里的汽车不感兴趣。我需要根据我所在的位置选择速度。

也许使用 fetch 模式作为 JOIN 的选项是可以接受的,因为在这种情况下它将只有两个查询(一个用于班级,一个用于学生),但我真的很喜欢可以选择在一个查询,特别是如果我有几个要加载的子集合并且不想对每个关系执行查询。我意识到一次性连接会创建需要流式传输的额外数据,但令我惊讶的是,这种级别的控制并不容易完成,或者可能完全不可用。

【问题讨论】:

  • 你的问题是什么?

标签: java hibernate orm lazy-evaluation eager


【解决方案1】:

Hibernate 没有非常方便的动态获取方式。你可以控制它

  1. Dynamic fetching via HQL queriesjoin fetch 一起使用(如@ThibaultClement 建议的那样)。
  2. Dynamic association fetchingCriteria.setFetchMode() 结合使用。
  3. Dynamic fetching via profiles@FetchProfile 注释一起使用。

您也可以参考HQL joined query to eager fetch a large number of relationships 了解更多想法。

【讨论】:

  • 很公平。我想确保我没有忽略一些明显的事情,特别是因为 Hibernate 有多种收集数据的方式。我只需要跳出“实体框架思维模式”,意识到不同的 ORM 不会有 1-1 对应的特性。
  • @AirmanAJK 可能是,如果你还没有去Querydsl 看看,对你来说会很有趣。
【解决方案2】:

正如@v.ladynev 所提到的,querydsl 是一个不错的选择。但是,在我看来,仍然没有一种干净的方法来处理它。

  1. 如果使用 .select(...),结果将是元组而不是原始实体(未提及的字段默认为 null),这将导致编写一些样板代码以将其映射到原始实体.
  2. 与 querydsl 相关的另一种可能的解决方案是使用 QueryProjection,但同样需要您编写一个具有不同可能性的单独类。
  3. 第三种解决方案可以是将所有连接保持为Fetch.LAZY,然后根据需要使用JpaUtils.initialize()(或hibernate 自己的方法)来获取实体图。 (但就性能而言,这会比直接使用join fetch 更糟糕,因为它只会进行 1 次 sql 调用。
  4. 值得关注的第三个选项的不同风格是使用 NamedEntityGraph 或 EntityGraph 来获取所需的部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多