JOOQ 中有没有办法在没有多个数据库调用的情况下提取大量记录?
Is there a way in JOOQ to pull a number of records without multiple DB calls?
在我们的网络应用程序中,我们有许多地方可以让您在一个复杂的 form/view 中更新多个 table。在原始 SQL 中,我可能会 select 来自一堆 table 的一堆列,并在主要 table 以及相关的 parent/child 上编辑该记录] tables.
在休眠中,我可能只是为主要 table 提取一个 JPA 实体,并让休眠在我填充视图时获取 parent/child 关系。然后从我的视图中拉回实体并调用 entitymanger .perist/merge.
在 JOOQ 中,我有很多选项,但您似乎可以通过 selectFrom/fetch 提取主记录,然后使用 fetchChild fetchParent 提取类型化的相关记录,如下所示...
LoadsRecord load = dslContext.selectFrom(LOADS)
.where(LOADS.ID.eq(id))
.fetchOne();
SafetyInspectionsRecord safetyInspection = load.fetchParent(Keys.LOADS__FK_SAFETY_INSPECTION);
所以这样我就能够以类型安全的方式提取相关记录。唯一烦人的是我每次调用 fetchParent 或 fetchDhild 时都必须 运行 另一个完整查询。有没有办法一次急切地获取所有这些以避免多次往返数据库?
拥有这些 类 用于 CRUD 屏幕的 LoadsRecord 真的很棒,它使更新数据库变得容易。
使用连接的经典方法
您可以通过多种方式实现 to-one 关系。最简单的是简单的 JOIN
或 LEFT JOIN
如果关系是可选的。
例如:
Result<?> result =
ctx.select()
.from(LOADS)
.join(SAFETY_INSPECTIONS)
.on(LOADS.SAFETY_INSPECTIONS_ID.eq(SAFETY_INSPECTIONS.ID))
.fetch();
之后您可能想使用生成的记录,因此您可以使用各种映射工具将通用 Record
类型映射到两个 UpdatableRecord
类型以进行进一步的 CRUD:
for (Record r : result) {
LoadsRecord loads = r.into(LOADS);
SafetyInspectionsRecord si = r.into(SAFETY_INSPECTIONS);
}
使用嵌套记录
从 jOOQ 3.15 开始,#11812, MULTISET
and ROW
运算符可用于创建嵌套的集合和记录。因此,在您的查询中,您可以这样写:
Result<?> result =
ctx.select(
row(LOADS.ID, ...),
row(SAFETY_INSPECTIONS.ID, ...))
.from(LOADS)
.join(SAFETY_INSPECTIONS)
.on(LOADS.SAFETY_INSPECTIONS_ID.eq(SAFETY_INSPECTIONS.ID))
.fetch();
这已经有助于将嵌套数据结构映射到所需的格式。从jOOQ 3.17和#4727开始,你甚至可以直接使用table表达式来生成嵌套记录:
Result<Record2<LoadsRecord, SafetyInspectionsRecord>> result =
ctx.select(LOADS, SAFETY_INSPECTIONS)
.from(LOADS)
.join(SAFETY_INSPECTIONS)
.on(LOADS.SAFETY_INSPECTIONS_ID.eq(SAFETY_INSPECTIONS.ID))
.fetch();
这项新功能肯定会弥补 jOOQ 的最大差距之一。您甚至可以使用 implicit joins 将上述内容简化为:
Result<Record2<LoadsRecord, SafetyInspectionsRecord>> result =
ctx.select(LOADS, LOADS.safetyInspections())
.from(LOADS)
.fetch();
在我们的网络应用程序中,我们有许多地方可以让您在一个复杂的 form/view 中更新多个 table。在原始 SQL 中,我可能会 select 来自一堆 table 的一堆列,并在主要 table 以及相关的 parent/child 上编辑该记录] tables.
在休眠中,我可能只是为主要 table 提取一个 JPA 实体,并让休眠在我填充视图时获取 parent/child 关系。然后从我的视图中拉回实体并调用 entitymanger .perist/merge.
在 JOOQ 中,我有很多选项,但您似乎可以通过 selectFrom/fetch 提取主记录,然后使用 fetchChild fetchParent 提取类型化的相关记录,如下所示...
LoadsRecord load = dslContext.selectFrom(LOADS)
.where(LOADS.ID.eq(id))
.fetchOne();
SafetyInspectionsRecord safetyInspection = load.fetchParent(Keys.LOADS__FK_SAFETY_INSPECTION);
所以这样我就能够以类型安全的方式提取相关记录。唯一烦人的是我每次调用 fetchParent 或 fetchDhild 时都必须 运行 另一个完整查询。有没有办法一次急切地获取所有这些以避免多次往返数据库?
拥有这些 类 用于 CRUD 屏幕的 LoadsRecord 真的很棒,它使更新数据库变得容易。
使用连接的经典方法
您可以通过多种方式实现 to-one 关系。最简单的是简单的 JOIN
或 LEFT JOIN
如果关系是可选的。
例如:
Result<?> result =
ctx.select()
.from(LOADS)
.join(SAFETY_INSPECTIONS)
.on(LOADS.SAFETY_INSPECTIONS_ID.eq(SAFETY_INSPECTIONS.ID))
.fetch();
之后您可能想使用生成的记录,因此您可以使用各种映射工具将通用 Record
类型映射到两个 UpdatableRecord
类型以进行进一步的 CRUD:
for (Record r : result) {
LoadsRecord loads = r.into(LOADS);
SafetyInspectionsRecord si = r.into(SAFETY_INSPECTIONS);
}
使用嵌套记录
从 jOOQ 3.15 开始,#11812, MULTISET
and ROW
运算符可用于创建嵌套的集合和记录。因此,在您的查询中,您可以这样写:
Result<?> result =
ctx.select(
row(LOADS.ID, ...),
row(SAFETY_INSPECTIONS.ID, ...))
.from(LOADS)
.join(SAFETY_INSPECTIONS)
.on(LOADS.SAFETY_INSPECTIONS_ID.eq(SAFETY_INSPECTIONS.ID))
.fetch();
这已经有助于将嵌套数据结构映射到所需的格式。从jOOQ 3.17和#4727开始,你甚至可以直接使用table表达式来生成嵌套记录:
Result<Record2<LoadsRecord, SafetyInspectionsRecord>> result =
ctx.select(LOADS, SAFETY_INSPECTIONS)
.from(LOADS)
.join(SAFETY_INSPECTIONS)
.on(LOADS.SAFETY_INSPECTIONS_ID.eq(SAFETY_INSPECTIONS.ID))
.fetch();
这项新功能肯定会弥补 jOOQ 的最大差距之一。您甚至可以使用 implicit joins 将上述内容简化为:
Result<Record2<LoadsRecord, SafetyInspectionsRecord>> result =
ctx.select(LOADS, LOADS.safetyInspections())
.from(LOADS)
.fetch();