使用Model API创建简单的JOOQ SQL查询

时间:2017-07-24 14:12:01

标签: java sql dsl jooq

我一直在使用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集成?

1 个答案:

答案 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();

手册的这些部分提供了更多信息:

使用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的工作方式相同。