【问题标题】:Making hibernate not include fields from joined tables in select clause使休眠不包括选择子句中连接表中的字段
【发布时间】:2009-02-10 19:52:56
【问题描述】:

我在使用 Hibernate 的 DetachedCriteria 的 SQL 中遇到了性能问题。我有一些多对一的关系,当 Hibernate 生成 SQL 时,它包括来自在 FROM 中连接的表中的所有字段。 发生这种情况时,MySQL 会花费很长时间来运行查询(其中还有一个 order by 和 sub query 添加到问题中)。对于我目前的 50k 记录 ~6sec。当我将 SELECT 中不必要的字段删除到我关心的域对象时,它的运行时间低于 500 毫秒。

有没有办法让 Hibernate 不包含连接中的字段?

我尝试将映射文件中的 fetch 参数设置为“join”和“select”,这对生成的 SQL 没有影响。

我也尝试过设置不同的根条目,但从我读过的内容来看,这不适用于分页(我也在这样做)。

我可以尝试将查询编写为 HQL,但使用子查询只会让人头疼。

【问题讨论】:

  • 现在指定投影有效(为每个指定别名);如果有一种简单的方法来投射实体。*那就太好了。我还必须设置结果转换器以使用 Transformers.aliasToBean(RootEntity.class)) 正确设置对象

标签: hibernate


【解决方案1】:

您可以设置一个仅包含您感兴趣的属性列表的 Projection。

这是一个过去项目的例子:

Criteria criteria = getSession().createCriteria(Something.class);
criteria.createCriteria("user", "u");

// only retrieve the following fields: id, state, viewCount, user.username
ProjectionList properties = Projections.projectionList();
properties.add(Projections.property("id"));
properties.add(Projections.property("state"));
properties.add(Projections.property("viewCount"));
properties.add(Projections.property("u.username"));

criteria.setProjection(properties);

【讨论】:

  • +1:我花了很多时间试图做到这一点。你的回答真的很有帮助。谢谢!
  • 有没有办法用注释做到这一点?用 @Transient 之类的东西标记该表或该表中的列?
【解决方案2】:

我有同样的问题,听起来很奇怪,没有办法做到这一点。 这听起来很常见,使用 JOIN 进行过滤,但不加载整个关联实体。

【讨论】:

    【解决方案3】:

    您是否尝试为不想加载的类设置 Lazy = true?

    【讨论】:

    • 我们默认为延迟加载,但由于连接,这些字段仍然是选择查询的一部分。正如我一直在阅读的那样,这种行为似乎是为了允许对来自连接的字段进行排序。
    猜你喜欢
    • 2012-02-12
    • 2018-06-13
    • 2012-10-16
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多