如何将jooq multiset的结果映射到Hashmap(Java Map)中?
How to map the result of jooq multiset into Hashmap(Java Map)?
我有以下class和查询。我想使用 multiset
将 images
的结果映射到 Map<String, String>
(Key: OrderNumber / Value: FileKey),但我不知道该怎么做。你能帮我如何将 multiset 结果映射到 hashmap 吗?
data class User(
val id: UUID,
val name: String,
val images: Map<String, String>?
)
@Repository
@Transactional(readOnly = true)
class FetchUserRepository(private val ctx: DSLContext) {
private val user = JUser.USER
private val userImage = JUserImage.USER_IMAGE
override fun fetch(): List<User> {
return ctx.select(
user.ID,
user.NAME,
multiset(
select(userImage.ORDER_NUMBER.cast(String::class.java), userImage.FILE_KEY)
.from(userImage)
.where(userImage.USER_ID.eq(user.ID))
).convertFrom { r -> r.map(mapping(???)) } // I'm not sure how to map the result to hashmap
)
.from(user)
.fetchInto(User::class.java)
}
jOOQ 3.16解决方案
您的 multiset()
表达式的类型是 Result<Record2<String, String>>
, so you can use the Result.intoMap(Field, Field)
method, or even Result.collect(Collector)
using the Records.intoMap()
收集器,这样可以避免重复字段名称:
{ r -> r.collect(Records.intoMap()) }
I've explained this more in detail in a blog post, here.
jOOQ 3.17解决方案
事实上,这看起来非常有用和强大,让我们使用一些扩展(位于 jOOQ-kotlin
扩展模块)在现有 API 之上添加一些便利:
// New extension functions, e.g.
fun <R : Record, E> Field<Result<R>>.collecting(collector: Collector<R, *, E>)
= convertFrom { it.collect(collector) }
fun <K, V> Field<Result<Record2<K, V>>>.intoMap(): Field<Map<K, V>>
= collecting(Records.intoMap())
// And then, you can write:
multiset(...).intoMap()
除了 Lukas 的回答,我还想提供一个替代选项 jsonObject
& jsonObjectAgg
。
此查询的结果将以 JSON 格式返回,并且可以通过 Jackson 或其他方式轻松地将其投影到目标 class。 (当涉及到目标中的嵌套集合时,这是一个非常强大的功能class)
我相信这是 jOOQ 最酷的功能之一,因为 MULTISET :)
data class User(
val id: UUID,
val name: String,
val images: Map<String, String>?
)
@Repository
@Transactional(readOnly = true)
class FetchUserRepository(private val ctx: DSLContext) {
private val user = JUser.USER
private val userImage = JUserImage.USER_IMAGE
override fun fetch(): List<User> {
return ctx.select(
jsonObject(
key("id").value(user.ID),
key("name").value(user.NAME),
key("images").value(
field(
select(
jsonObjectAgg(
userImage.ORDER_NUMBER.cast(String::class.java),
userImage.FILE_KEY
)
)
.from(userImage)
.where(userImage.USER_ID.eq(user.ID))
)
)
)
)
.from(user)
.fetchInto(User::class.java)
}
}
我有以下class和查询。我想使用 multiset
将 images
的结果映射到 Map<String, String>
(Key: OrderNumber / Value: FileKey),但我不知道该怎么做。你能帮我如何将 multiset 结果映射到 hashmap 吗?
data class User(
val id: UUID,
val name: String,
val images: Map<String, String>?
)
@Repository
@Transactional(readOnly = true)
class FetchUserRepository(private val ctx: DSLContext) {
private val user = JUser.USER
private val userImage = JUserImage.USER_IMAGE
override fun fetch(): List<User> {
return ctx.select(
user.ID,
user.NAME,
multiset(
select(userImage.ORDER_NUMBER.cast(String::class.java), userImage.FILE_KEY)
.from(userImage)
.where(userImage.USER_ID.eq(user.ID))
).convertFrom { r -> r.map(mapping(???)) } // I'm not sure how to map the result to hashmap
)
.from(user)
.fetchInto(User::class.java)
}
jOOQ 3.16解决方案
您的 multiset()
表达式的类型是 Result<Record2<String, String>>
, so you can use the Result.intoMap(Field, Field)
method, or even Result.collect(Collector)
using the Records.intoMap()
收集器,这样可以避免重复字段名称:
{ r -> r.collect(Records.intoMap()) }
I've explained this more in detail in a blog post, here.
jOOQ 3.17解决方案
事实上,这看起来非常有用和强大,让我们使用一些扩展(位于 jOOQ-kotlin
扩展模块)在现有 API 之上添加一些便利:
// New extension functions, e.g.
fun <R : Record, E> Field<Result<R>>.collecting(collector: Collector<R, *, E>)
= convertFrom { it.collect(collector) }
fun <K, V> Field<Result<Record2<K, V>>>.intoMap(): Field<Map<K, V>>
= collecting(Records.intoMap())
// And then, you can write:
multiset(...).intoMap()
除了 Lukas 的回答,我还想提供一个替代选项 jsonObject
& jsonObjectAgg
。
此查询的结果将以 JSON 格式返回,并且可以通过 Jackson 或其他方式轻松地将其投影到目标 class。 (当涉及到目标中的嵌套集合时,这是一个非常强大的功能class)
我相信这是 jOOQ 最酷的功能之一,因为 MULTISET :)
data class User(
val id: UUID,
val name: String,
val images: Map<String, String>?
)
@Repository
@Transactional(readOnly = true)
class FetchUserRepository(private val ctx: DSLContext) {
private val user = JUser.USER
private val userImage = JUserImage.USER_IMAGE
override fun fetch(): List<User> {
return ctx.select(
jsonObject(
key("id").value(user.ID),
key("name").value(user.NAME),
key("images").value(
field(
select(
jsonObjectAgg(
userImage.ORDER_NUMBER.cast(String::class.java),
userImage.FILE_KEY
)
)
.from(userImage)
.where(userImage.USER_ID.eq(user.ID))
)
)
)
)
.from(user)
.fetchInto(User::class.java)
}
}