【问题标题】:Creating a plain JOOQ SQL query using the Model API使用模型 API 创建一个普通的 JOOQ SQL 查询
【发布时间】:2017-12-30 04:06:09
【问题描述】:

我一直在使用 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 中找不到工厂方法,这种用例的最佳方法是什么?

虽然我可以设置值并执行 .getSQL() 以获取带有 ? 的 SQL,但还有另一个步骤是获取绑定变量以将其传递给 PreparedStatement,是否可以一步完成?

如何将其与 JDBCTemplate 集成?

【问题讨论】:

  • “有没有办法动态创建 SELECTION 查询” - 抱歉,我不确定你的意思。你在挣扎什么? / “我在 3.6.x 中找不到工厂方法” - 你说得对,我会在那里编辑我的答案。

标签: java sql dsl jooq


【解决方案1】:

首先,您将术语 model API 放在问题标题中,但您没有使用 model API,您使用的是 DSL API,更适合“静态SQL查询”。因此,这将是更合适的 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 的工作方式相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-09
    • 2018-11-23
    • 2012-12-12
    • 2014-12-21
    • 1970-01-01
    • 2020-02-21
    • 2015-10-12
    • 2019-10-17
    相关资源
    最近更新 更多