Querydsl JPQLQuery fetchAll purpose

Querydsl JPQLQuery fetchAll purpose

我们正在将一个项目从 Querydsl 版本 3 更新到版本 4。子查询的工作方式发生了变化。在版本 3 中,您可以编写这样的子查询:

ListSubQuery<Long> subQueryResult = new JPASubQuery()
    .from(domain)
    .where(domain.prefix.eq(prefix))
    .list(domain.id);

我将代码升级为:

JPQLQuery<Long> subQueryResult = from(domain)
    .select(domain.id)
    .where(domain.prefix.eq(prefix))
    .fetchAll();

我的问题是关于我在查询末尾添加的方法 fetchAll。我不确定是否有必要。我以为它是 list 的替代品,但我的同事指出 return 类型只是 JPQLQuery,它已经被 编辑了 return其中.

fetchAll 的 JavaDoc 指出:

Add the "fetchJoin all properties" flag to the last defined join.

这对我来说毫无意义。实验似乎表明这个调用是没有必要的,但这仍然留下了一个问题——它有什么用?我可以安全地将它从我的子查询中删除吗?

您需要 fetchJoin() 才能实际加载标记为 "lazy" 的属性。这对你的例子来说意义不大(只加载一个 domain.id 值),但如果你开始在子查询中加载复杂的数据类型,你可能实际上希望你的数据出现在你的根查询中。

话虽这么说,具有具有 "lots of" 惰性属性的复杂数据类型,您可能不希望/不需要将获取标志添加到所有这些,而只是添加到您查询实际需要的那些。所以仅仅调用 fetchAll 可能并不是你一直需要的。如有疑问,我会建议启用 sql 日志记录并分析生成的 sql,每个 JOIN FETCH 都是一个急切的负载。

And can I safely remove it from my sub-query

所以 TL;DR:如果您过去从未想过 JOIN FETCH,那么实际上:是的,您应该能够安全地忽略 fetchAll,因为它不会向您的查询添加任何新内容。它应该只是一种省去一些样板代码的便捷方式,以防您真的想要完全预加载数据。