当前位置: 首页 > 面试题库 >

如何使用jOOQ从模板按参数生成SQL?

江阳冰
2023-03-14
问题内容

我使用jOOQ 3.11.11生成了这样的SQL模板。

DSLContext context = new DefaultDSLContext(conf);
Query query = context.select()
    .from("table1")
    .where(DSL.field("report_date").eq(DSL.param("bizdate")))
    .orderBy(DSL.param("sort"));
String sqlTemp = context.renderNamedParams(query);

SQL模板:

select * 
from table1 
where report_date = :bizdate 
order by :sort

将存储SQL模板,并根据实时查询条件确定参数。

ResultQuery resultQuery = context.resultQuery(sqlTemp, DSL.param("bizdate", "20190801"), DSL.param("sort", "id desc"));

实时SQL:

select * 
from table1 
where report_date = '20190801' 
order by 'id desc'

order by子句有问题。

所以。如何用 “ id desc”“ name asc” 用param 排序 替换订单并消除引号?


问题答案:

DSL.param()创建一个绑定变量,该绑定变量的生成方式?与SQL一样,或者:bizdate您选择使用命名参数,或者'20190801'选择内联绑定变量。有关绑定变量的更多信息,请参见此处。

您不能用于DSL.param()生成列引用或关键字。jOOQ表达式树中按Field类型描述了列表达式(例如,引用)。关键字是按Keyword类型描述的,但是您可能不想降低这个级别。相反,您想处理查询表达式中的某些逻辑。例如:

String sortField = "id";
SortOrder sortOrder = SortOrder.ASC;

Query query = context.select()
    .from("table1")
    .where(DSL.field("report_date").eq(DSL.param("bizdate")))
    .orderBy(DSL.field(sortField).sort(sortOrder));

您犯的错误是认为您可以对各种不同的动态SQL查询使用单个SQL模板,但是如果要动态添加另一个谓词呢?还是另一个加入?还是另一列?无论如何,您都必须构建一个不同的jOOQ表达式树。就像这里。您可以存储两个SQL字符串(每个排序顺序一个),并为每个排序列重复该字符串。

但是,建议您提取一个采用输入参数并每次重新生成查询的函数,而不是预先生成单个SQL字符串,例如:

ResultQuery<?> query(String bizDate, Field<?> sortField, SortOrder sortOrder) {
    return context.selectFrom("table1")
                  .where(field("report_date").eq(bizDate))
                  .orderBy(sortField.sort(sortOrder));
}

以下是有关将jOOQ用于动态SQL的更多信息:

  • https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql
  • https://blog.jooq.org/2017/01/16/a-functional-programming-approach-to-dynamic-sql-with-jooq


 类似资料:
  • 我用jOOQ 3.11.11生成了这样的SQL模板。 SQL模板: 存储SQL模板,并在实时查询条件下确定参数。 实时SQL: 从句顺序有问题。 所以如何将order by param sort替换为“id desc”或“name asc”,并删除引号?

  • MySQL不接受此处生成的datetime值。我探索并发现jOOQ转换器可以用于自定义转换。我可以找到如何在获取数据时使用转换的示例,但无法弄清楚如何在查询时使用转换器。如何使用jOOQ转换器生成SQL而不生成代码?或者是否有更好的方法为SQL生成此查询。

  • 我希望一个类有两种不同的实现,并根据布尔模板参数进行选择。我尝试使用本答案中描述的SFINAE原则,如下所示: 然而,我在gcc下遇到了一个错误“不能在类范围内专门化函数”,我不明白为什么。虽然我的代码与链接答案中的代码并不完全相同,但它似乎非常相似,我无法发现关键的区别。 我还尝试使用类似于此答案中建议的语法,但也不起作用(错误是“不能重新声明类成员”): 我怎样才能做到这一点?

  • 我有以下问题:一个类模板a,有几个模板参数,我想构建一个类B,它以a为模板参数,并提取a的第一个模板参数,以便在某种方法中使用它(想想从std::vector 中提取int并返回默认的int{})。 我知道这种天真的方法不会编译,但我不知道如何实现这样的东西。感谢任何提示。

  • 问题内容: 我目前正在尝试从jpa实体生成jooq类,而不是使用现有的数据库。 跟随此页面并使用jooq版本3.9.1,我当前的pom插件部分如下所示 当运行maven软件包时,这确实会成功,但是不会生成预期的jooq类。构建的堆栈跟踪显示: 问题答案: 您的实体可能与放置插件的位置位于同一模块中。这意味着jOOQ代码生成器在编译模块之前被调用,这意味着当jOOQ代码生成器尝试查找带有JPA注释的

  • 本质上,我想要一个具有数组的模板类,其大小是一个模板参数,以保存常量内容。 类似于: 我一直在搜索和修补一点,几乎有一个解决方法实现了一个中间静态方法,并使用std::array: ...这已经是相当多的样板,但仍然d::array似乎不是从初始化列表中构建的?:-(