如何使用 Jooq 映射实体?
How can I map entity using a Jooq?
我有一个问题:不知道如何映射 Jooq 查询的结果。
我有 2 个实体:付款方式和货币。 Payment method里面包含一个List。两者都存储在不同的表中。
我得到一个:
public Optional<PaymentMethod> getMethod(Long id) {
return this.dslContext.selectFrom(PAYMENT_METHOD)
.where(
PAYMENT_METHOD.ID.eq(id),
PAYMENT_METHOD.DELETED.eq(false)
).fetchOptional().map(v -> methodDao.mapper().map(v));
也想获得货币,方法是:
return this.dslContext.select(asterisk())
.from(PAYMENT_METHOD)
.join(PAYMENT_METHOD_CURRENCY)
.on(PAYMENT_METHOD_CURRENCY.METHOD_ID.eq(id))
.where(
PAYMENT_METHOD.ID.eq(id),
PAYMENT_METHOD.DELETED.eq(false)
)
.fetch()
.map(...)...
那么,我该如何进一步映射呢?
我决定在其他实体中使用单个实体,例如:
private PaymentProviderMethod mapMethod(Record record) {
final PaymentMethodRecord methodRecord = record.into(PAYMENT_METHOD);
final PaymentProviderRecord providerRecord = record.into(PAYMENT_PROVIDER);
return new PaymentProviderMethod(
methodDao.mapper().map(methodRecord),
providerDao.mapper().map(providerRecord));
但不知道在这种情况下如何映射列表。你能帮忙吗?
如果你想用 jOOQ 嵌套集合,那么你可能正在寻找 MULTISET
or MULTISET_AGG
operator along with ad-hoc conversion, which allows for type safe nesting collections directly in SQL, if your database product support SQL/XML or SQL/JSON。
以下可能不是您要查找的确切查询,但您明白了:
// Assuming the usual static import:
import static org.jooq.impl.DSL.*;
ctx.select(
PAYMENT_METHOD.ID,
PAYMENT_METHOD.PROVIDER_ID,
PAYMENT_METHOD.NAME,
...
multiset(
select(
PAYMENT_METHOD_CURRENCY.ID,
PAYMENT_METHOD_CURRENCY.NAME,
...
)
.from(PAYMENT_METHOD_CURRENCY)
.where(PAYMENT_METHOD_CURRENCY.METHOD_ID.eq(PAYMENT_METHOD.ID))
).convertFrom(r -> r.map(Records.mapping(Currency::new)))
)
.from(PAYMENT_METHOD)
.fetch(Records.mapping(PaymentMethod::new))
上面的例子使用 MULTISET
作为嵌套的相关子查询,但是你可以用 MULTISET_AGG
和 JOIN
和 GROUP BY
子句做同样的事情,特别是如果您的方言不支持 correlating derived tables, see issue #12045。整个查询是类型安全的。如果您更改 PaymentMethod
或 Currency
DTO 类,查询将停止编译,直到您修复预测。
如果你使用的 Jooq 版本低于 13.15
那么你不能使用 multiset。对我来说,我遇到了同样的问题,我通过手动映射记录解决了这个问题。我用 Kotlin 做到了这一点,但我认为你可以从那里弄清楚这个想法:
private fun mapRecords(records: Result<Record>): List<PaymentMethod> {
val paymentMethodCurrencies = records.into(PaymentMethodCurrencyRecord::class.java)
.map(::mapPaymentMethodCurrency)
.groupBy { it.paymentMethodId }
val paymentMethods = records.into(PaymentMethodRecord::class.java).distinct()
.map {
mapPaymentMethod(it, paymentMethodCurrencies[it.id])
}
return paymentMethods
}
我有一个问题:不知道如何映射 Jooq 查询的结果。
我有 2 个实体:付款方式和货币。 Payment method里面包含一个List。两者都存储在不同的表中。
我得到一个:
public Optional<PaymentMethod> getMethod(Long id) {
return this.dslContext.selectFrom(PAYMENT_METHOD)
.where(
PAYMENT_METHOD.ID.eq(id),
PAYMENT_METHOD.DELETED.eq(false)
).fetchOptional().map(v -> methodDao.mapper().map(v));
也想获得货币,方法是:
return this.dslContext.select(asterisk())
.from(PAYMENT_METHOD)
.join(PAYMENT_METHOD_CURRENCY)
.on(PAYMENT_METHOD_CURRENCY.METHOD_ID.eq(id))
.where(
PAYMENT_METHOD.ID.eq(id),
PAYMENT_METHOD.DELETED.eq(false)
)
.fetch()
.map(...)...
那么,我该如何进一步映射呢?
我决定在其他实体中使用单个实体,例如:
private PaymentProviderMethod mapMethod(Record record) {
final PaymentMethodRecord methodRecord = record.into(PAYMENT_METHOD);
final PaymentProviderRecord providerRecord = record.into(PAYMENT_PROVIDER);
return new PaymentProviderMethod(
methodDao.mapper().map(methodRecord),
providerDao.mapper().map(providerRecord));
但不知道在这种情况下如何映射列表。你能帮忙吗?
如果你想用 jOOQ 嵌套集合,那么你可能正在寻找 MULTISET
or MULTISET_AGG
operator along with ad-hoc conversion, which allows for type safe nesting collections directly in SQL, if your database product support SQL/XML or SQL/JSON。
以下可能不是您要查找的确切查询,但您明白了:
// Assuming the usual static import:
import static org.jooq.impl.DSL.*;
ctx.select(
PAYMENT_METHOD.ID,
PAYMENT_METHOD.PROVIDER_ID,
PAYMENT_METHOD.NAME,
...
multiset(
select(
PAYMENT_METHOD_CURRENCY.ID,
PAYMENT_METHOD_CURRENCY.NAME,
...
)
.from(PAYMENT_METHOD_CURRENCY)
.where(PAYMENT_METHOD_CURRENCY.METHOD_ID.eq(PAYMENT_METHOD.ID))
).convertFrom(r -> r.map(Records.mapping(Currency::new)))
)
.from(PAYMENT_METHOD)
.fetch(Records.mapping(PaymentMethod::new))
上面的例子使用 MULTISET
作为嵌套的相关子查询,但是你可以用 MULTISET_AGG
和 JOIN
和 GROUP BY
子句做同样的事情,特别是如果您的方言不支持 correlating derived tables, see issue #12045。整个查询是类型安全的。如果您更改 PaymentMethod
或 Currency
DTO 类,查询将停止编译,直到您修复预测。
如果你使用的 Jooq 版本低于 13.15
那么你不能使用 multiset。对我来说,我遇到了同样的问题,我通过手动映射记录解决了这个问题。我用 Kotlin 做到了这一点,但我认为你可以从那里弄清楚这个想法:
private fun mapRecords(records: Result<Record>): List<PaymentMethod> {
val paymentMethodCurrencies = records.into(PaymentMethodCurrencyRecord::class.java)
.map(::mapPaymentMethodCurrency)
.groupBy { it.paymentMethodId }
val paymentMethods = records.into(PaymentMethodRecord::class.java).distinct()
.map {
mapPaymentMethod(it, paymentMethodCurrencies[it.id])
}
return paymentMethods
}