使用模型 API 创建普通 JOOQ SQL 查询
Creating a plain JOOQ SQL query using the Model API
我一直在使用 JOOQ,它似乎是一个非常有用的库,可以生成 SQL 查询。但是,我坚持动态生成它们。例如,下面是我想做的(注意,我只是想用它来做 SQL 构建而不生成任何代码)
DSLContext context = DSL.using(SQLDialect.DEFAULT);
List<Field<?>> select = getSelect(String fields ...); // gets the selection fields
Select query = create.select(select)
.from(name("table"));
if(where)
query = query.addWhere(Conditions...);
if(groupBy)
query = query.groupBy(List<Field<?>> ...);
if(orderBy)
query = query.orderBy(List<Field<?>> ...);
不幸的是,我只能找到一种方法来一步完成它们,如下所示:
query.select()
.from(...)
.where(...)
.orderBy(...)
.fetch();
如果 .where、.orderBy 可以接受 null,然后不将这些子句添加到 SQL(如果它们为 null),则上述内容可能会有用,但似乎这是不可能的。
这是我的问题:
有没有一种方法可以动态创建一个 SELECTION 查询,然后在不使用任何代码生成的情况下验证它,因为我的用例只涉及构建一个纯字符串 SQL?这个答案: 似乎不再有效,因为我在 3.6.x 中找不到工厂方法,这种用例的最佳方法是什么?
虽然我可以设置值并执行 .getSQL() 以获得带有 ? 的 SQL,但还有一个步骤是获取绑定变量,以便我将其传递给 PreparedStatement , 是否可以一步完成?
如何将其与 JDBCTemplate 集成?
首先,您在问题标题中使用了术语 模型 API,但您没有使用 模型 API,您正在使用 DSL API,它更适合 "static SQL queries"。所以,这将是更合适的 API 用法:
List<Field<?>> select = getSelect(String fields ...);
SelectQuery<?> query = create.selectQuery();
query.addFrom(table(name("table")));
if(where)
query.addWhere(Conditions...);
if(groupBy)
query.addGroupBy(List<Field<?>> ...);
if(orderBy)
query.addOrderBy(List<Field<?>> ...);
关于您的具体问题:
将 getSQL()
与绑定变量一起使用
事实上,默认情况下,jOOQ 总是会在其 SQL 语句中生成绑定变量,这在大多数数据库中是性能方面更好的默认选择。 Here's some background information on that topic.
如果你真的想要内联绑定变量,使用Query.getSQL(ParamType.INLINED)
. However, you probably want to keep using bind variables, so you can extract them from the query as follows, using Query.getBindVariables()
:
String sql = query.getSQL();
List<Object> variables = query.getBindVariables();
手册中这些部分的更多信息:
- https://www.jooq.org/doc/latest/manual/sql-building/bind-values
- https://www.jooq.org/doc/latest/manual/sql-execution/alternative-execution-models/using-jooq-with-jpa/using-jooq-with-jpa-native
正在使用 JDBCTemplate 执行查询
下面是一个示例,说明如何使用上述 getSQL()
和 getBindVariables()
方法 (from the manual) 将执行绑定到 JPA 的本机查询 API:
static List<Object[]> nativeQuery(EntityManager em, org.jooq.Query query) {
// Extract the SQL statement from the jOOQ query:
Query result = em.createNativeQuery(query.getSQL());
// Extract the bind values from the jOOQ query:
List<Object> values = query.getBindValues();
for (int i = 0; i < values.size(); i++) {
result.setParameter(i + 1, values.get(i));
}
return result.getResultList();
}
它与 JDBCTemplate 的工作方式相同。
我一直在使用 JOOQ,它似乎是一个非常有用的库,可以生成 SQL 查询。但是,我坚持动态生成它们。例如,下面是我想做的(注意,我只是想用它来做 SQL 构建而不生成任何代码)
DSLContext context = DSL.using(SQLDialect.DEFAULT);
List<Field<?>> select = getSelect(String fields ...); // gets the selection fields
Select query = create.select(select)
.from(name("table"));
if(where)
query = query.addWhere(Conditions...);
if(groupBy)
query = query.groupBy(List<Field<?>> ...);
if(orderBy)
query = query.orderBy(List<Field<?>> ...);
不幸的是,我只能找到一种方法来一步完成它们,如下所示:
query.select()
.from(...)
.where(...)
.orderBy(...)
.fetch();
如果 .where、.orderBy 可以接受 null,然后不将这些子句添加到 SQL(如果它们为 null),则上述内容可能会有用,但似乎这是不可能的。
这是我的问题:
有没有一种方法可以动态创建一个 SELECTION 查询,然后在不使用任何代码生成的情况下验证它,因为我的用例只涉及构建一个纯字符串 SQL?这个答案: 似乎不再有效,因为我在 3.6.x 中找不到工厂方法,这种用例的最佳方法是什么?
虽然我可以设置值并执行 .getSQL() 以获得带有 ? 的 SQL,但还有一个步骤是获取绑定变量,以便我将其传递给 PreparedStatement , 是否可以一步完成?
如何将其与 JDBCTemplate 集成?
首先,您在问题标题中使用了术语 模型 API,但您没有使用 模型 API,您正在使用 DSL API,它更适合 "static SQL queries"。所以,这将是更合适的 API 用法:
List<Field<?>> select = getSelect(String fields ...);
SelectQuery<?> query = create.selectQuery();
query.addFrom(table(name("table")));
if(where)
query.addWhere(Conditions...);
if(groupBy)
query.addGroupBy(List<Field<?>> ...);
if(orderBy)
query.addOrderBy(List<Field<?>> ...);
关于您的具体问题:
将 getSQL()
与绑定变量一起使用
事实上,默认情况下,jOOQ 总是会在其 SQL 语句中生成绑定变量,这在大多数数据库中是性能方面更好的默认选择。 Here's some background information on that topic.
如果你真的想要内联绑定变量,使用Query.getSQL(ParamType.INLINED)
. However, you probably want to keep using bind variables, so you can extract them from the query as follows, using Query.getBindVariables()
:
String sql = query.getSQL();
List<Object> variables = query.getBindVariables();
手册中这些部分的更多信息:
- https://www.jooq.org/doc/latest/manual/sql-building/bind-values
- https://www.jooq.org/doc/latest/manual/sql-execution/alternative-execution-models/using-jooq-with-jpa/using-jooq-with-jpa-native
正在使用 JDBCTemplate 执行查询
下面是一个示例,说明如何使用上述 getSQL()
和 getBindVariables()
方法 (from the manual) 将执行绑定到 JPA 的本机查询 API:
static List<Object[]> nativeQuery(EntityManager em, org.jooq.Query query) {
// Extract the SQL statement from the jOOQ query:
Query result = em.createNativeQuery(query.getSQL());
// Extract the bind values from the jOOQ query:
List<Object> values = query.getBindValues();
for (int i = 0; i < values.size(); i++) {
result.setParameter(i + 1, values.get(i));
}
return result.getResultList();
}
它与 JDBCTemplate 的工作方式相同。