简体   繁体   English

我可以使用jOOQ将纯SQL查询映射到生成的pojo中吗?

[英]Can I use jOOQ to map a plain SQL query into a generated pojo?

I'm executing a plain sql query in jOOQ and would like to map it into a jOOQ generated pojo. 我正在jOOQ中执行一个简单的SQL查询,并希望将其映射到jOOQ生成的pojo。 I was hoping that I could to something like this: 我希望我能做到这样的事情:

public List<Foo> findFoos(final DateTime time) {
    return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
             .fetchInto(Foo.class);
}

However this does not work. 但是这不起作用。 The fields do not get mapped to the types required to build a Foo as the field definitions are those of the DB columns, not the mapped types of the FOO table. 这些字段不会映射到构建Foo所需的类型,因为字段定义是DB列的字段定义,而不是FOO表的映射类型。 Currently my code looks something like this: 目前我的代码看起来像这样:

public List<Foo> findFoos(final DateTime time) {
    return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
             .fetch(r -> {
                 return new Foo(
                         new FooId(r.getValue(FOO.ID, UUID.class)),
                         new BarId(r.getValue(FOO.BAR_ID, UUID.class))
                         //etc
                 );
             });
}

Is there some way I can provide the result query with the list of Field s that I am fetching so it can map the result correctly? 有没有什么方法可以提供结果查询与我正在获取的Field列表,以便它可以正确映射结果? I am hoping that somewhere there is the ability to do something like this instead: 我希望在某个地方有能力做这样的事情:

public List<Foo> findFoos(final DateTime time) {
    return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
             .fetch(FOO.fields())
             .into(Foo.class);
}

However I can't find it. 但是我找不到它。 Is this a thing somewhere that I am overlooking or is this not supported? 这是我忽视的某个地方还是不受支持?

For reference, one of the reasons I am using plain sql is to get intervals to work in PostgreSQL. 作为参考,我使用普通sql的原因之一是让间隔在PostgreSQL中工作。 eg (not the real query) 例如(不是真正的查询)

select
    f.*
from foo f
where f.id not in (
    select
        x.foo_id
    from bar x
    where x.start_date >= (?::timestamptz - '1 year'::interval)
)

Thanks in advance. 提前致谢。

jOOQ 3.12 solution jOOQ 3.12解决方案

jOOQ 3.12 implements #4473 , which allows for coercing a ResultQuery<R1> to a new, well-known record type ResultQuery<R2> (possibly with Converter or Binding configurations). jOOQ 3.12实现了#4473 ,它允许将ResultQuery<R1>转换为新的,众所周知的记录类型ResultQuery<R2> (可能使用ConverterBinding配置)。

You could write: 你可以写:

public List<Foo> findFoos(final DateTime time) {
    return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
             .coerce(FOO)
             .fetch();
}

Workaround for jOOQ 3.11 and earlier versions jOOQ 3.11及更早版本的解决方法

You don't necessarily have to resort to all-plain SQL. 您不一定要使用全纯SQL。 You could do this instead: 你可以这样做:

public List<Foo> findFoos(final DateTime time) {
    return db.select(FOO.fields())
             .from("({0}) AS {1}", 
                  DSL.sql(loadSqlQuery("FooRepository_findFoos"), time),
                  DSL.name(FOO.getName()))
             .fetchInto(Foo.class);
}

You'd have to make sure that FOO.fields() doesn't generate any schema names, eg by specifying Settings.renderSchema = false 您必须确保FOO.fields()不生成任何模式名称,例如通过指定Settings.renderSchema = false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM