我一直在使用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然后如果它们为null则不将这些子句添加到SQL中,则上述一个可能很有用,但似乎不可能。
以下是我的问题:
有没有办法动态创建SELECTION查询,然后在不使用任何代码生成的情况下对其进行验证,因为我的用例只涉及构造一个普通的String SQL?这个答案:https://stackoverflow.com/a/14053108/1787599f似乎不再有效,因为我在3.6.x中找不到Factory方法,这种用例的最佳方法是什么?
虽然我可以设置值并使用.getSQL()来获取带有?的SQL,但还有另一个步骤是让我将绑定变量传递给PreparedStatement,它可以在一个步骤中完成吗? / p>
如何将其与JDBCTemplate集成?
答案 0 :(得分:1)
首先,您将模型API 这个词放在问题标题中,但是您没有使用模型API ,您正在使用 DSL API ,更适合&#34;静态SQL查询&#34;。因此,这将是更合适的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)
。但是,您可能希望继续使用绑定变量,因此可以使用Query.getBindVariables()
从查询中提取它们:
String sql = query.getSQL();
List<Object> variables = query.getBindVariables();
手册的这些部分提供了更多信息:
以下是使用上述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的工作方式相同。