我可以使用 jOOQ 将普通 SQL 查询映射到生成的 pojo 中吗?
Can I use jOOQ to map a plain SQL query into a generated pojo?
我正在 jOOQ 中执行一个简单的 sql 查询,并想将其映射到 jOOQ 生成的 pojo 中。我希望我能做到这样的事情:
public List<Foo> findFoos(final DateTime time) {
return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
.fetchInto(Foo.class);
}
但是这不起作用。这些字段没有映射到构建 Foo
所需的类型,因为字段定义是 DB 列的定义,而不是 FOO table 的映射类型。目前我的代码看起来像这样:
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
);
});
}
有什么方法可以为结果查询提供我正在获取的 Field
列表,以便它可以正确映射结果?我希望某个地方有能力做这样的事情:
public List<Foo> findFoos(final DateTime time) {
return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
.fetch(FOO.fields())
.into(Foo.class);
}
但是我找不到它。这是我忽略的地方还是不受支持?
作为参考,我使用普通 sql 的原因之一是让间隔在 PostgreSQL 中工作。例如(不是真正的查询)
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)
)
提前致谢。
jOOQ 3.12解决方案
jOOQ 3.12 实现 #4473,它允许将 ResultQuery<R1>
强制转换为新的众所周知的记录类型 ResultQuery<R2>
(可能使用 Converter
或 Binding
配置)。
你可以这样写:
public List<Foo> findFoos(final DateTime time) {
return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
.coerce(FOO)
.fetch();
}
jOOQ 3.11 及更早版本的解决方法
您不一定非得求助于普通 SQL。您可以这样做:
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);
}
您必须确保 FOO.fields()
不会生成任何架构名称,例如通过指定 Settings.renderSchema = false
我正在 jOOQ 中执行一个简单的 sql 查询,并想将其映射到 jOOQ 生成的 pojo 中。我希望我能做到这样的事情:
public List<Foo> findFoos(final DateTime time) {
return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
.fetchInto(Foo.class);
}
但是这不起作用。这些字段没有映射到构建 Foo
所需的类型,因为字段定义是 DB 列的定义,而不是 FOO table 的映射类型。目前我的代码看起来像这样:
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
);
});
}
有什么方法可以为结果查询提供我正在获取的 Field
列表,以便它可以正确映射结果?我希望某个地方有能力做这样的事情:
public List<Foo> findFoos(final DateTime time) {
return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
.fetch(FOO.fields())
.into(Foo.class);
}
但是我找不到它。这是我忽略的地方还是不受支持?
作为参考,我使用普通 sql 的原因之一是让间隔在 PostgreSQL 中工作。例如(不是真正的查询)
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)
)
提前致谢。
jOOQ 3.12解决方案
jOOQ 3.12 实现 #4473,它允许将 ResultQuery<R1>
强制转换为新的众所周知的记录类型 ResultQuery<R2>
(可能使用 Converter
或 Binding
配置)。
你可以这样写:
public List<Foo> findFoos(final DateTime time) {
return db.resultQuery(loadSqlQuery("FooRepository_findFoos"), time)
.coerce(FOO)
.fetch();
}
jOOQ 3.11 及更早版本的解决方法
您不一定非得求助于普通 SQL。您可以这样做:
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);
}
您必须确保 FOO.fields()
不会生成任何架构名称,例如通过指定 Settings.renderSchema = false