jooq, simpleflatmapper, kotlin 映射

Posted

技术标签:

【中文标题】jooq, simpleflatmapper, kotlin 映射【英文标题】:jooq, simpleflatmapper, kotlin mapping 【发布时间】:2021-12-26 18:57:17 【问题描述】:

我正在将一个 java 项目转换为 kotlin,但在使用查询结果构造数据对象时出错。查询是 Docs 和 Questions 之间具有一对多关系的联接。这在 java 中有效,但我无法让它与 kotlin 一起使用。我尝试过提供默认值并使用无参数项目。不确定这是 kotlin、jooq 还是简单的平面映射器问题。

Spring boot: 2.5.4
kotlin: 1.5.31

implementation 'org.simpleflatmapper:sfm-jooq:8.2.3'
implementation 'org.springframework.boot:spring-boot-starter-jooq'



@Repository
open class DocRepository(private val dslContext: DSLContext) 
    companion object : KLogging()

    private val docMapper = SelectQueryMapperFactory.newInstance().newMapper(
        Doc::class.java
    )

override fun getDocDetails(docId: Int): Doc 
        return docMapper.asList(
            dslContext.select(
                Tables.DOC.DOC_ID,
                Tables.DOC.TITLE,
                Tables.DOC.DESCRIPTION,
                Tables.DOC.QUESTION.QUESTION_ID,
                Tables.DOC.QUESTION.DOC_ID,
                Tables.DOC.QUESTION.QUESTION,
                Tables.DOC.QUESTION.ANSWER
            )
                .from(Tables.DOC).leftJoin(Tables.QUESTION)
                .on(Tables.QUESTION.DOC_ID.eq(Tables.DOC.DOC_ID))
                .where(Tables.DOC.DOC_ID.eq(docId))
        ).stream().findFirst().get()
    






data class Doc(
    var docId: Int? = null,
    val title: String? = "",
    val description: String? = "",
    var questions: List<Question?>? = null,
)


data class Question(
    var questionId: Int? = null,
    var docId: Int? = null,
    var question: String? = "",
    var answer: String? = ""
)



org.jooq.exception.MappingException: No constructor available for class com.test.entity.Doc
at org.simpleflatmapper.jooq.SelectQueryMapper.getMapper(SelectQueryMapper.java:186)
at org.simpleflatmapper.jooq.SelectQueryMapper.asList(SelectQueryMapper.java:46)

【问题讨论】:

我不确定,但如果您添加 @NoArgsConstructor,您还需要将 @AllArgsConstructor 添加到 Doc 类中。 这是使用 kotlin-noarg 项目创建的自定义注解。它似乎不适用于这个问题。这不是龙目岛注释。 我只是认为可能是 NoArgs 注释阻止了 jooq 能够创建 Doc 类的实例所需的隐式构造函数。 【参考方案1】:

我无法评论您的 SimpleFlatMapper 用法,但从 jOOQ 3.15 开始,如果您的底层 SQL 数据库产品以某种方式支持 SQL/JSON or SQL/XML,则有更好的嵌套集合方法:使用 new MULTISET (or MULTISET_AGG) operator!

override fun getDocDetails(docId: Int): Doc 
    return dslContext.select(
            DOC.DOC_ID,
            DOC.TITLE,
            DOC.DESCRIPTION,
            multiset(
                select(
                    QUESTION.QUESTION_ID,
                    QUESTION.DOC_ID,
                    QUESTION.QUESTION,
                    QUESTION.ANSWER
                )
                .from(QUESTION)
                .where(QUESTION.DOC_ID.eq(DOC.DOC_ID))
            ).convertFrom  it.map(Records.mapping(::Question)) 
        )
        .from(DOC)
        .where(DOC.DOC_ID.eq(docId))
        .fetchSingle(Records.mapping(::Doc))
    

这是所有类型安全且无反射的。

【讨论】:

以上是关于jooq, simpleflatmapper, kotlin 映射的主要内容,如果未能解决你的问题,请参考以下文章

新的 jooq/gradle 配置不生成任何 jooq 类

JOOQ + Gradle:如何为 JOOQ 生成器定义多个模式?

尝试更新到“org.jooq:jooq-codegen-maven:3.15.1”时构建失败

JOOQ + JPA 实体

jOOQ 不使用自定义数据绑定

jOOQ